// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include <stdio.h>
#include "Game.h"

#include <ddraw.h>	// DirectDraw
#pragma comment(lib,"ddraw.lib")
#pragma comment(lib,"dxguid.lib")


#include "MainFrm.h"


#include <imm.h>	// 关闭输入法
#pragma comment (lib, "imm32.lib")

HIMC g_hImc;
void DisableIME(HWND hWnd)
{
    g_hImc = ImmGetContext(hWnd);
    if (g_hImc) {
        ImmAssociateContext(hWnd, NULL);
	}
    ImmReleaseContext(hWnd, g_hImc);
    ::SetFocus(hWnd);
}


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_CREATE()
	ON_WM_MOUSEMOVE()
	ON_WM_RBUTTONDOWN()
	ON_WM_LBUTTONDOWN()
	ON_WM_SETCURSOR()
	ON_MESSAGE( ID_GAME_MESSAGE, OnGameMessage )
	ON_WM_NCMOUSEMOVE()
	ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMainFrame 构造/销毁
CMainFrame::CMainFrame()
{
	m_pBufDC     = NULL;
	m_pTitleDC   = NULL;
	m_pBarDC     = NULL;
	m_pButtonsDC = NULL;
    m_pBombDC    = NULL;
	m_pDlgDC     = NULL;
    m_pCursorDC  = NULL;
	m_pMidi      = new CMidi;
	m_pGameMap   = NULL;

	m_pBmp       = new CBmp;
	m_pAvi       = new CAvi[AVI_MAX];

	m_bScreenClosed = FALSE;
	m_bTabKeyState = FALSE;
	m_nCurButton = 0;
	m_nLevelUpCounter = 0;
	m_byKeyStatus = 0;
	m_byDirection = 0;
	m_nLastCommandType = 0;
	m_nMessageDelay = 0;
	m_nTalkDelay = 0;
	memset( m_paBullet, 0x0, sizeof(int)*4*3 );
    memset( m_paCannon, 0x0, sizeof(int)*3 );

	m_pRainbowDC = NULL;
	m_nChangeColor = 0;
	m_nButtonNextColor = 0;
	m_pLeftPhotoDC  = NULL;
	m_pRightPhotoDC = NULL;
	m_pItemPhotoDC  = NULL;

	m_pScript = new CScript;

    m_bDDrawOK = FALSE;
    m_pDDraw   = NULL;
    
	m_mouse_azimuth = 0;
	m_mouse_pointer = CPoint(0, 0);
	m_weapon_change = FALSE;
    
	// 设置游戏为开始态
	m_nST = GAME_ST_START;
}

CMainFrame::~CMainFrame()
{
	ReleaseAll();
}

void CMainFrame::QuitGame()
{
	PostQuitMessage( WM_QUIT );
}

void CMainFrame::ReleaseAll()
{
	if( m_pBufDC != NULL )
	{
		delete m_pBufDC;
		m_pBufDC = NULL;
	}
	if( m_pTitleDC != NULL )
	{
		delete m_pTitleDC;
		m_pTitleDC = NULL;
	}
	if( m_pBarDC != NULL )
	{
		delete m_pBarDC;
		m_pBarDC = NULL;
	}
	if( m_pButtonsDC != NULL )
	{
		delete m_pButtonsDC;
		m_pButtonsDC = NULL;
	}
    if( m_pBombDC != NULL )
    {
        delete m_pBombDC;
        m_pBombDC = NULL;
    }
	if( m_pDlgDC != NULL )
	{
		delete m_pDlgDC;
		m_pDlgDC = NULL;
	}
    if( m_pCursorDC != NULL )
    {
        delete m_pCursorDC;
        m_pCursorDC = NULL;
    }
    if( m_pCursorMaskDC != NULL )
    {
        delete m_pCursorMaskDC;
        m_pCursorMaskDC = NULL;
    }
	if( m_pMidi != NULL )
	{
		delete m_pMidi;
		m_pMidi = NULL;
	}
	if( m_pGameMap != NULL )
	{
		delete m_pGameMap;
		m_pGameMap = NULL;
	}
	if( m_pRainbowDC != NULL )
	{
		delete m_pRainbowDC;
		m_pRainbowDC = NULL;
	}
	if( m_pBmp != NULL )
	{
		delete m_pBmp;
		m_pBmp = NULL;
	}
	if( m_pAvi != NULL )
	{
		delete [] m_pAvi;
		m_pAvi = NULL;
	}
	if( m_pLeftPhotoDC != NULL )
	{
		delete m_pLeftPhotoDC;
		m_pLeftPhotoDC = NULL;
	}
	if( m_pRightPhotoDC != NULL )
	{
		delete m_pRightPhotoDC;
		m_pRightPhotoDC = NULL;
	}
	if( m_pItemPhotoDC != NULL )
	{
		delete m_pItemPhotoDC;
		m_pItemPhotoDC = NULL;
	}
	if( m_pScript != NULL )
	{
		delete m_pScript;
		m_pScript = NULL;
	}
    if( m_bDDrawOK )
    {
        if( m_pDDraw != NULL )
        {
            m_pDDraw->Release();
            m_pDDraw = NULL;
        }
        m_bDDrawOK = FALSE;
    }
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	// 重要 ！！！下列代码禁用中文输入法
	// 如果不禁用输入法，快捷键ASDF默认输入中文
	DisableIME (GetSafeHwnd());

	// 创建一个游戏地图
	m_pGameMap = new CGameMap( this );

	// 初始化
	m_pMidi->Init( m_hWnd );

	// 支持鼠标双击必须增加 CS_DBLCLKS 属性
	DWORD classStyle = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
	SetClassLong(m_hWnd, GCL_STYLE, classStyle);

// 初始化与DirectDraw相关的内容
    while( 1 )
    {
        // 提问玩家是否启用DirectX
        int ret = MessageBox("启用全屏幕模式吗？","请问",MB_YESNOCANCEL|MB_ICONQUESTION);

        if( ret == IDYES )
        {
            if( !InitDirectDraw() )
            {
                MessageBox( DDRAW_FAILURE );
                m_bDDrawOK = FALSE;
            }
            else
            {
                m_bDDrawOK = TRUE;
                // 消隐鼠标光标
                ShowCursor( FALSE );
            }

            break;
        }
        else if( ret == IDNO )
        {
            m_bDDrawOK = FALSE;
            break;
        }
        else
        {
			ShowCursor(TRUE);
            ret = MessageBox("您打算退出游戏吗？","请问",MB_YESNO|MB_ICONEXCLAMATION);
			ShowCursor(FALSE);
            if( ret == IDYES )
                exit(0);
        }
    }

	//如果Direct模式初始化成功，那么马上获取Direct窗口尺寸
	if (m_bDDrawOK) {
		GetClientRect(&m_rcDDrawWindow);
	}

	// 注意，虽然在创建Direct表面的时候指定了800×600分辨率，
	// 但是创建出来之后，要根据GetWindowRect获得的实际Direct表面尺寸来绘图
	//CString info;
	//info.Format("w: %d  h: %d", m_rcDDrawWindow.Width(), m_rcDDrawWindow.Height());
	//MessageBox(info);

// 与DirectDraw相关的内容初始化完毕
	CDC* pDC = GetDC();

    // 初始化光标及相关DC
    HBITMAP hBmpCursor = (HBITMAP)LoadImage(NULL,FILENAME_IMG_CURSOR,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    HBITMAP hBmpCursorMask = ::CreateBitmap( CURSOR_W, CURSOR_H, 1, 1, NULL );

    m_pCursorDC = new CDC;
    m_pCursorMaskDC = new CDC;
    m_pCursorDC->CreateCompatibleDC( pDC );
    m_pCursorMaskDC->CreateCompatibleDC( pDC );

    m_pCursorDC->SetBkColor( COLORKEY );
    m_pCursorDC->SetTextColor( RGB(0,0,0) );
    DeleteObject( m_pCursorDC->SelectObject( hBmpCursor ) );
    DeleteObject( m_pCursorMaskDC->SelectObject( hBmpCursorMask ) );

    m_pCursorMaskDC->SetBkColor( RGB(255,255,255) );
    m_pCursorMaskDC->SetTextColor( RGB(0,0,0) );
    m_pCursorMaskDC->BitBlt( 0, 0, CURSOR_W, CURSOR_H, m_pCursorDC, 0, 0, SRCCOPY );

	// 将开始画面读入内存
	m_pTitleDC = new CDC;
	m_pTitleDC->CreateCompatibleDC( pDC );
	HBITMAP hbmp1=(HBITMAP)LoadImage(NULL,FILENAME_IMG_TITLE,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
	DeleteObject( m_pTitleDC->SelectObject( hbmp1 ) );

	// 将状态栏背景读入内存
	m_pBarDC = new CDC;
	m_pBarDC->CreateCompatibleDC( pDC );
	HBITMAP hbmp2=(HBITMAP)LoadImage(NULL,FILENAME_IMG_BAR,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
	DeleteObject( m_pBarDC->SelectObject( hbmp2 ) );

	// 将按钮位图读入内存
	m_pButtonsDC = new CDC;
	m_pButtonsDC->CreateCompatibleDC( pDC );
	HBITMAP hbmp3=(HBITMAP)LoadImage(NULL,FILENAME_IMG_BUTTONS,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
	DeleteObject( m_pButtonsDC->SelectObject( hbmp3 ) );

    // 将爆炸图片读入内存
    m_pBombDC = new CDC;
    m_pBombDC->CreateCompatibleDC( pDC );
    HBITMAP hbmp4=(HBITMAP)LoadImage(NULL,FILENAME_IMG_BOMB,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    DeleteObject( m_pBombDC->SelectObject( hbmp4) );

	// 创建缓冲区用于存放对话栏
	m_pDlgDC = new CDC;
	m_pDlgDC->CreateCompatibleDC( pDC );
	CBitmap bmp2;
	bmp2.CreateCompatibleBitmap( pDC, DIALOG_W, DIALOG_H );
	DeleteObject( m_pDlgDC->SelectObject( &bmp2 ) );
	CFont font2;
	font2.CreateFont(16,0,0,0,400,FALSE,FALSE,0,
		GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"宋体");
	DeleteObject( m_pDlgDC->SelectObject( &font2 ) );
	// 设置文字模式为背景透明
	m_pDlgDC->SetBkMode( TRANSPARENT );

	// 读入彩虹位图
	m_pRainbowDC = new CDC;
	m_pRainbowDC->CreateCompatibleDC( pDC );
	HBITMAP hbmp5 = (HBITMAP)LoadImage(NULL,FILENAME_IMG_RAINBOW,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
	DeleteObject( m_pRainbowDC->SelectObject( hbmp5 ) );

	// 初始化背景图片和动画群
	m_pBmp->Init( pDC );

	int i;
	for( i=0; i<AVI_MAX; i++ )
		m_pAvi[i].Init( pDC );

	// 初始化屏幕缓冲区
	m_pBufDC = new CDC;
	m_pBufDC->CreateCompatibleDC( pDC );
	CBitmap bmpBuffer;
    if( m_bDDrawOK )
		bmpBuffer.CreateCompatibleBitmap( pDC, m_rcDDrawWindow.Width(), m_rcDDrawWindow.Height() );
    else
	    bmpBuffer.CreateCompatibleBitmap( pDC, SCREEN_W, SCREEN_H );
	DeleteObject( m_pBufDC->SelectObject( &bmpBuffer ) );
	CFont font;
	font.CreateFont(16,0,0,0,400,FALSE,FALSE,0,
		GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"宋体");
	DeleteObject( m_pBufDC->SelectObject( &font ) );
	// 设置文字模式为背景透明
	m_pBufDC->SetBkMode( TRANSPARENT );

    ReleaseDC( pDC );

	// 设置鼠标光标
    HCURSOR hcr = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
    SetCursor( hcr );

	if (! m_bDDrawOK) {
		// 如果DDraw初始化不成功，那么咱们就继续用MFC窗口模式
		LONG_PTR Style = WS_CAPTION | WS_SYSMENU;
		LONG_PTR ExStyle = WS_EX_CLIENTEDGE;

		//设置修改后的属性值
		::SetWindowLongPtr(m_hWnd, GWL_STYLE, Style);
		::SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, ExStyle);

		//修改窗口位置
		CRect rcWindow;
		int cx = SCREEN_W + 20;		//长度
		int cy = SCREEN_H + GetSystemMetrics(SM_CYCAPTION) + 20;		//高度
		rcWindow.left = ((GetSystemMetrics(SM_CXSCREEN) - cx) / 2);
		rcWindow.top  = ((GetSystemMetrics(SM_CYSCREEN) - cy) / 2);
		rcWindow.right = rcWindow.left + cx;
		rcWindow.bottom = rcWindow.top + cy;

		MoveWindow (&rcWindow);
	}

	return 0;
}

// 初始化DirectDraw系统
BOOL CMainFrame::InitDirectDraw()
{
	if (DD_OK != (DirectDrawCreateEx(NULL, (void **)&m_pDDraw, IID_IDirectDraw7, NULL)))
		return (FALSE);
	
	if (DD_OK != (m_pDDraw->SetCooperativeLevel(m_hWnd,
		DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)))
		return (FALSE);

	if (DD_OK != (m_pDDraw->SetDisplayMode(DIRECT_SCREEN_W, DIRECT_SCREEN_H, 32,0,0)))
		return (FALSE);

    return TRUE;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;

	// 修改窗口的显示位置
	cs.style = WS_POPUP;
	cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
	cs.hMenu = NULL;
	// 如果使用带系统条的窗口，则需要调整窗口生成的位置和尺寸

	cs.lpszClass = AfxRegisterWndClass(0);

	// 设置标题
	SetTitle(GAME_TITLE);

	return TRUE;
}

void CMainFrame::MakeBuffer()
{
    // 如果初始化DirectDraw成功，需要在pdc上面绘制底纹
    m_pBufDC->BitBlt( 0,0,GAME_AREA_W,GAME_AREA_H, m_pBufDC, 0,0, BLACKNESS );

	// 如果屏幕处于关闭状态，则除了对话栏和状态栏以外什么都不绘制
	if( m_bScreenClosed )
	{
		// 绘制状态栏
		DrawBar( m_pBufDC, 0, 0 );

		// 对话栏打开状态还要绘制对话栏
		if( m_nST > 10 )
			DrawDialog( m_pBufDC, 0, 0 );

		return;
	}

	int i;

	// 开始状态时，状态栏覆盖整个窗口
	if( ((m_nST % 10) == GAME_ST_FIGHT) ||
		((m_nST % 10) == GAME_ST_WALK) )
	{
		// 绘制游戏地图
		m_pGameMap->Draw( m_pBufDC->GetSafeHdc(), 0, 0 );

        if( m_nCurWeapen != WEAPEN_GUN4 )
		    // 绘制子弹的特效
		    DrawBullets( m_pBufDC, 0, 0 );
        else
            // 绘制炮弹的特效
            DrawCannonBomb( m_pBufDC, 0, 0 );
	}

	// 只有对话态才绘制背景位图
	if( (m_nST % 10) == GAME_ST_DIALOG )
		m_pBmp->Draw( m_pBufDC, 0, 0 );

	// 绘制动画组
	for( i=0; i<AVI_MAX; i++ )
		m_pAvi[i].Draw( m_pBufDC, 0, 0 );

	// 绘制状态栏
	DrawBar( m_pBufDC, 0, 0 );

	// 对话栏打开状态还要绘制对话栏
	if( m_nST > 10 )
		DrawDialog( m_pBufDC, 0, 0 );
}

void CMainFrame::Paint()
{
	// 将缓冲区送上屏幕
    if( m_bDDrawOK )
    {
        // 仅在最后一次输出使用DirectX虽然速度快不了多少，
        // 但有一个明显的好处：可以避免画面“撕裂”，
        // （画面更新与显示器场频不同步造成的轻微闪烁）
        MakeDirectBuffer();
        DirectPaint(m_pBufDC);
    }
    else
    {
        // 在主缓冲区中准备好将要送上屏幕的内容
	    MakeBuffer();
        // 未使用DirectX，直接将画面内容写入GDI设备
	    CDC* pdc = GetDC();
	    pdc->BitBlt( 0,0,SCREEN_W,SCREEN_H,m_pBufDC,0,0,SRCCOPY );
	    ReleaseDC( pdc );
    }
}

// 向DirectDraw表面输出CDC的内容，并交换表面显示之
void CMainFrame::DirectPaint(CDC* psrc)
{
	CDC* pdc = GetDC();
	pdc->BitBlt( 0,0,m_rcDDrawWindow.Width(),m_rcDDrawWindow.Height(),psrc,0,0,SRCCOPY );
	ReleaseDC( pdc );
}


// 为Direct方式绘制准备画面内容
void CMainFrame::MakeDirectBuffer()
{
	int scr_w = m_rcDDrawWindow.Width();
	int scr_h = m_rcDDrawWindow.Height();

    // 绘制游戏画面
	int x = (scr_w - SCREEN_W) / 2;
	int y = (scr_h - SCREEN_H) / 2;

    m_pBufDC->BitBlt( x,y,GAME_AREA_W,GAME_AREA_H, m_pBufDC, x,y, BLACKNESS );

	// 如果屏幕处于关闭状态，则除了对话栏和状态栏以外什么都不绘制
	if( m_bScreenClosed )
	{
		// 绘制状态栏
		DrawBar( m_pBufDC, x, y );

		// 对话栏打开状态还要绘制对话栏
		if( m_nST > 10 )
			DrawDialog( m_pBufDC, x, y );

		goto DrawBackGround;
	}

	int i;

	// 开始状态时，状态栏覆盖整个窗口
	if( ((m_nST % 10) == GAME_ST_FIGHT) ||
		((m_nST % 10) == GAME_ST_WALK) )
	{
		// 绘制游戏地图
		m_pGameMap->Draw( m_pBufDC->GetSafeHdc(), x, y );

        if( m_nCurWeapen != WEAPEN_GUN4 )
		    // 绘制子弹的特效
		    DrawBullets( m_pBufDC, x, y );
        else
            // 绘制炮弹的特效
            DrawCannonBomb( m_pBufDC, x, y );
	}

	// 只有对话态才绘制背景位图
	if( (m_nST % 10) == GAME_ST_DIALOG )
		m_pBmp->Draw( m_pBufDC, x, y );

	// 绘制动画组
	for( i=0; i<AVI_MAX; i++ )
		m_pAvi[i].Draw( m_pBufDC, x, y );

	// 绘制状态栏
	DrawBar( m_pBufDC, x, y );

	// 对话栏打开状态还要绘制对话栏
	if( m_nST > 10 )
		DrawDialog( m_pBufDC, x, y );

DrawBackGround:
// 由于Driect条件下屏幕的分辨率比游戏窗口大，
// 需要在pdc上面绘制底纹，以填补游戏窗口之外的黑色区域。

	int y1 = (scr_h - SCREEN_H) / 2 - BACK_GROUND_TILE_H;
	int y2 = (scr_h - SCREEN_H) / 2 + SCREEN_H;
	for( i=0; i<scr_w; i+=BACK_GROUND_TILE_H )
    {
        m_pBufDC->BitBlt( i, y1, BACK_GROUND_TILE_W, BACK_GROUND_TILE_H, 
                      m_pButtonsDC, 0, 186, SRCCOPY );
        m_pBufDC->BitBlt( i, y2, BACK_GROUND_TILE_W, BACK_GROUND_TILE_H, 
                      m_pButtonsDC, 0, 186, SRCCOPY );
    }

	int x1 = (scr_w - SCREEN_W) / 2 - BACK_GROUND_TILE_W + 1;
	int x2 = (scr_w - SCREEN_W) / 2 + SCREEN_W;
    for( i=(DIRECT_SCREEN_H - SCREEN_H) / 2; i<y2; i+=BACK_GROUND_TILE_H )
    {
        m_pBufDC->BitBlt( x1, i, BACK_GROUND_TILE_W, BACK_GROUND_TILE_H, 
                      m_pButtonsDC, 0, 186, SRCCOPY );
        m_pBufDC->BitBlt( x2, i, BACK_GROUND_TILE_W, BACK_GROUND_TILE_H, 
                      m_pButtonsDC, 0, 186, SRCCOPY );
    }

	// 绘制鼠标光标
	m_pBufDC->BitBlt(m_mouse_pointer.x+x,m_mouse_pointer.y+y,CURSOR_W,CURSOR_H,m_pCursorDC,0,0,SRCINVERT);
	m_pBufDC->BitBlt(m_mouse_pointer.x+x,m_mouse_pointer.y+y,CURSOR_W,CURSOR_H,m_pCursorMaskDC,0,0,SRCAND);
	m_pBufDC->BitBlt(m_mouse_pointer.x+x,m_mouse_pointer.y+y,CURSOR_W,CURSOR_H,m_pCursorDC,0,0,SRCINVERT);
}

LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) 
	{
	case MM_MCINOTIFY:
		m_pMidi->ReplayMidi(wParam);
		break;
	case WM_DESTROY:
		m_pMidi->StopMidi();	//退出时关闭Midi
		break;
	default:
		return CFrameWnd::WindowProc(message, wParam, lParam);
   }
   return 1;
}

void CMainFrame::ActProc( long lNow )
{
	// 动画动作的推进
	int i;
	for( i=0; i<AVI_MAX; i++ )
		m_pAvi[i].Proc( lNow );

	// 事件延时，防止事件被连续响应
	if (m_nMessageDelay > 0)
		m_nMessageDelay --;

	// 对话结束后的延施
	if (m_nTalkDelay > 0)
		m_nTalkDelay --;

	// 处理延时事件
	if( m_nLastCommandType == COMMAND_DELAY )
	{
		if( m_nMessageDelay == 0 )
		{
			// 通知事件处理函数继续执行脚本
			PostMessage( ID_GAME_MESSAGE, COMMAND_DELAY );
		}
		return;
	}

	// 对话栏打开状态，只处理关闭对话栏的操作
	if( m_nST > 10 )
	{
		if( GetAsyncKeyState(VK_SPACE) || GetAsyncKeyState(VK_RETURN))
		{
			// 必须在延时完成后才能响应Next按钮
			if( m_nMessageDelay == 0 )
			{
				CloseDialog();
				// 通知事件处理函数继续执行脚本
				PostMessage( ID_GAME_MESSAGE, COMMAND_DIALOG, 0 );
			}
		}
		return;
	}

	int nST = m_nST % 10;
	if (nST == GAME_ST_START)
		return;

	BYTE byKeyStatus = 0;

	//根据鼠标状态做出处理。键盘处理比鼠标优先，如果键盘动作已经发生，则不重复处理
	if (GetAsyncKeyState(VK_LBUTTON) < 0 //左键按着是行走
		&& (nST == GAME_ST_WALK || nST == GAME_ST_FIGHT)) {
		switch (m_mouse_azimuth) {
		case DIRECTION_UP:
			byKeyStatus = KEY_STATUS_UP;
			break;
		case DIRECTION_DOWN:
			byKeyStatus = KEY_STATUS_DOWN;
			break;
		case DIRECTION_LEFT:
			byKeyStatus = KEY_STATUS_LEFT;
			break;
		case DIRECTION_RIGHT:
			byKeyStatus = KEY_STATUS_RIGHT;
			break;
		}
	}

	//鼠标和键盘同时操作时，键盘优先。键盘可以覆盖鼠标操作
	// 在上下左右四个键中，优先响应最后被按下的键
	if(GetAsyncKeyState(VK_UP) || GetAsyncKeyState('W'))
		byKeyStatus = KEY_STATUS_UP;
	if(GetAsyncKeyState(VK_DOWN) || GetAsyncKeyState('S'))
		byKeyStatus = KEY_STATUS_DOWN;
	if(GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState('A'))
		byKeyStatus = KEY_STATUS_LEFT;
	if(GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState('D'))
		byKeyStatus = KEY_STATUS_RIGHT;


	if( byKeyStatus != 0 ) // 有按键按下或者鼠标按下的情况
	{
		// 如果与上次按键状态相同，则继续执行上次的动作
		if( byKeyStatus != m_byKeyStatus )
		{
			// 优先响应新按下的按键
			BYTE byStatus = byKeyStatus;
			byStatus &= ~m_byKeyStatus;
			if( byStatus > 0 )
			{
				// 检测新按下的是哪个键
				if     ( (byStatus & KEY_STATUS_UP)    > 0 )
					m_byDirection = DIRECTION_UP;
				else if( (byStatus & KEY_STATUS_DOWN)  > 0 )
					m_byDirection = DIRECTION_DOWN;
				else if( (byStatus & KEY_STATUS_LEFT)  > 0 )
					m_byDirection = DIRECTION_LEFT;
				else if( (byStatus & KEY_STATUS_RIGHT) > 0 )
					m_byDirection = DIRECTION_RIGHT;
			}
			else
			{
				// 看是否有按键弹起，如果有按键弹起，则响应剩下的键
				byStatus = byKeyStatus;
				if( byStatus > 0 )
				{
					// 检测剩下的是哪个键
					if     ( (byStatus & KEY_STATUS_UP)    > 0 )
						m_byDirection = DIRECTION_UP;
					else if( (byStatus & KEY_STATUS_DOWN)  > 0 )
						m_byDirection = DIRECTION_DOWN;
					else if( (byStatus & KEY_STATUS_LEFT)  > 0 )
						m_byDirection = DIRECTION_LEFT;
					else if( (byStatus & KEY_STATUS_RIGHT) > 0 )
						m_byDirection = DIRECTION_RIGHT;
				}
			}
		}

		// 行走
		switch (m_byDirection)
		{
		case DIRECTION_UP:
			m_pGameMap->GoUp(lNow);
			break;
		case DIRECTION_DOWN:
			m_pGameMap->GoDown(lNow);
			break;
		case DIRECTION_LEFT:
			m_pGameMap->GoLeft(lNow);
			break;
		case DIRECTION_RIGHT:
			m_pGameMap->GoRight(lNow);
			break;
		}
	}
	else
	{
		// 在方向键和鼠标左键都没有按下的时候，按照鼠标的位置原地旋转角色
		if (nST == GAME_ST_FIGHT)
		{
			if (m_mouse_azimuth != 0 &&	m_byDirection != m_mouse_azimuth)
			{
				if (m_pGameMap->m_pHero->ActComplete()) {
					m_byDirection = m_mouse_azimuth;
					m_pGameMap->m_pHero->SetDirection(m_mouse_azimuth);
				}
			}
		}
	}

	// 记录此次方向键的按键状态
	m_byKeyStatus = byKeyStatus;
	// 方向键处理结束

	if (GetAsyncKeyState(VK_TAB))
	{
		// 切换武器(切换武器键不能自动连续)
		if( !m_bTabKeyState )
		{
			int nOldWeapon = m_nCurWeapen;
			ChangeWeapon();
			if (nOldWeapon != m_nCurWeapen) {
				m_weapon_change = TRUE;
			}
			m_bTabKeyState = TRUE;
		}
	}
	else
	{
		m_bTabKeyState = FALSE;
	}

	if (m_weapon_change) {
		// 刚换了武器，如果弹夹不满，自动装弹
		switch (m_nCurWeapen) {
		case WEAPEN_GUN1:
			if (m_stGun1.nCurAmmo < m_stGun1.nMaxAmmo) {
				OnRenewCassette(lNow); 
			}
			break;
		case WEAPEN_GUN2:
			if (m_stGun2.nCurAmmo < m_stGun2.nMaxAmmo) {
				OnRenewCassette(lNow); 
			}
			break;
		case WEAPEN_GUN3:
			if (m_stGun3.nCurAmmo < m_stGun3.nMaxAmmo) {
				OnRenewCassette(lNow); 
			}
			break;
		case WEAPEN_GUN4:
			if (m_stGun4.nCurAmmo < m_stGun4.nMaxAmmo) {
				OnRenewCassette(lNow); 
			}
			break;
		}

		m_weapon_change = FALSE;
	}

	if (m_nST == GAME_ST_FIGHT &&
		(GetAsyncKeyState(VK_SPACE) || GetAsyncKeyState(VK_RBUTTON)<0))//鼠标右键按着
	{
		// 射击
		OnFire( lNow );
	}

	if(GetAsyncKeyState('R'))
	{
		// 重装弹夹
		OnRenewCassette( lNow );
	}

	m_pGameMap->MoveObjects (lNow, m_mouse_pointer);
}

// 射击
void CMainFrame::OnFire( long lNow )
{
	// 检验角色手中是否持有武器
	if( !m_pGameMap->m_pHero->HaveGun() )
		return;

	struct _WEAPEN* pWeapen;

	switch (m_nCurWeapen)
	{
	case WEAPEN_GUN1:
		pWeapen = &m_stGun1;
		break;
	case WEAPEN_GUN2:
		pWeapen = &m_stGun2;
		break;
	case WEAPEN_GUN3:
		pWeapen = &m_stGun3;
		break;
	case WEAPEN_GUN4:
		pWeapen = &m_stGun4;
		break;
	default:
		return;
	}

	// 判断是否满足开枪条件
	if( !pWeapen->bValid )
		return;
		
	// 弹夹没有子弹，执行装子弹动作
	if( pWeapen->nCurAmmo == 0 )
	{
		if (pWeapen->nCount != 0) {
			OnRenewCassette(lNow);
			return;
		}
		else if (m_stGun2.bValid && m_stGun2.nCount != 0) {
			//如果本枪没有子弹，首先换AK47
			pWeapen = &m_stGun2;
			m_nCurWeapen = WEAPEN_GUN2;
			return;
		}
		else if (m_stGun1.bValid && m_stGun1.nCount != 0) {
			//如果AK47也没子弹了，那么换MP5
			pWeapen = &m_stGun1;
			m_nCurWeapen = WEAPEN_GUN1;
			return;
		}

		//没抢可换，就抱着空枪吧
		return;
	}

	// 刚刚完成对话，可以换弹夹，但是不可以开枪
	if (m_nTalkDelay > 0)
		return;

	if( !m_pGameMap->Fire( lNow, pWeapen->lShootDelay ) )
		return;

	// 减少当前弹夹的子弹数量
	pWeapen->nCurAmmo --;

	// 获得子弹威力
	int weapen_power = pWeapen->nPower;

    // 射击!
    if (m_nCurWeapen == WEAPEN_GUN4)
    {
        // 开炮
        int center_x, center_y, direction;
        m_pGameMap->CannonShot (weapen_power, &direction, &center_x, &center_y);
        m_paCannon[0] = 1;
        m_paCannon[1] = direction;
        m_paCannon[2] = center_x;
        m_paCannon[3] = center_y;
    }
    else
    {
	    // 子弹飞行的碰撞检测处理
	    int bullet_x, bullet_y;

	    int nHeroCount = 1;
	    if( m_pGameMap->m_pHero->HaveHero2() )
		    nHeroCount = 2;

    	// 有几个角色，就打几枪
	    while( nHeroCount-- )
	    {
		    if( m_pGameMap->BulletGo( weapen_power, &bullet_x, &bullet_y ) )
		    {
			    // 子弹碰上敌人，则添加一个子弹动画
			    int nItem;
			    for( nItem=0; nItem<4; nItem++ )
			    {
				    if( m_paBullet[nItem][0] == 0 )
				    {
					    m_paBullet[nItem][0] = 1;
					    m_paBullet[nItem][1] = bullet_x;
					    m_paBullet[nItem][2] = bullet_y;
					    break;
				    }
			    }
		    }
	    }
    }

	// 播放音效
	switch( m_nCurWeapen )
	{
	case WEAPEN_GUN1:
		m_pMidi->PlayWave( FILENAME_WAV_SHOOT1 );
		break;
	case WEAPEN_GUN2:
		m_pMidi->PlayWave( FILENAME_WAV_SHOOT2 );
		break;
	case WEAPEN_GUN3:
		m_pMidi->PlayWave( FILENAME_WAV_SHOOT3 );
		break;
	case WEAPEN_GUN4:
		m_pMidi->PlayWave( FILENAME_WAV_SHOOT4 );
		break;
	}
}

// 切换武器
void CMainFrame::ChangeWeapon(void)
{
	switch (m_nCurWeapen)
	{
	case WEAPEN_GUN1:
		if (m_stGun2.bValid && m_stGun2.GetAmmoCount() != 0)
		{
			m_nCurWeapen = WEAPEN_GUN2;
			m_pMidi->PlayWave (FILENAME_WAV_CHANGE_GUN);
			break;
		}
	case WEAPEN_GUN2:
		if (m_stGun3.bValid && m_stGun3.GetAmmoCount() != 0)
		{
			m_nCurWeapen = WEAPEN_GUN3;
			m_pMidi->PlayWave (FILENAME_WAV_CHANGE_GUN);
			break;
		}
	case WEAPEN_GUN3:
		if (m_stGun4.bValid && m_stGun4.GetAmmoCount() != 0)
		{
			m_nCurWeapen = WEAPEN_GUN4;
			m_pMidi->PlayWave (FILENAME_WAV_CHANGE_GUN);
			break;
		}
	case WEAPEN_GUN4:
		if (m_stGun1.bValid && m_stGun1.GetAmmoCount() != 0)
		{
			m_nCurWeapen = WEAPEN_GUN1;
			m_pMidi->PlayWave (FILENAME_WAV_CHANGE_GUN);
			break;
		}
	default:
		{
			if (m_stGun2.bValid && m_stGun2.GetAmmoCount() != 0)
			{
				m_nCurWeapen = WEAPEN_GUN2;
				m_pMidi->PlayWave (FILENAME_WAV_CHANGE_GUN);
				break;
			}
			if (m_stGun3.bValid && m_stGun3.GetAmmoCount() != 0)
			{
				m_nCurWeapen = WEAPEN_GUN3;
				m_pMidi->PlayWave (FILENAME_WAV_CHANGE_GUN);
				break;
			}
			if (m_stGun4.bValid && m_stGun4.GetAmmoCount() != 0)
			{
				m_nCurWeapen = WEAPEN_GUN4;
				m_pMidi->PlayWave (FILENAME_WAV_CHANGE_GUN);
				break;
			}
			break;
		}
	}

}

// 重装弹夹
void CMainFrame::OnRenewCassette( long lNow )
{
	struct _WEAPEN* pWeapen;

	switch (m_nCurWeapen)
	{
	case WEAPEN_GUN1:
		pWeapen = &m_stGun1;
		break;
	case WEAPEN_GUN2:
		pWeapen = &m_stGun2;
		break;
	case WEAPEN_GUN3:
		pWeapen = &m_stGun3;
		break;
	case WEAPEN_GUN4:
		pWeapen = &m_stGun4;
		break;
	default:
		pWeapen = &m_stGun1;
	}

	// 看是否可以更新当前弹夹
	if(  pWeapen->bValid && 
		(pWeapen->nCurAmmo < pWeapen->nMaxAmmo) &&
		(pWeapen->nCount != 0)
		)
	{
		if( m_pGameMap->RenewCassette( lNow, pWeapen->lRenewCassetteDelay ) )
		{
			m_pMidi->PlayWave( FILENAME_WAV_RENEW_CASSETTE );

			// 从总数中抽取子弹装入弹夹
			if( pWeapen->nCount == -1 )
			{
				// -1表示子弹无限
				pWeapen->nCurAmmo = pWeapen->nMaxAmmo;
			}
			else if( pWeapen->nCount < (pWeapen->nMaxAmmo - pWeapen->nCurAmmo) )
			{
				pWeapen->nCurAmmo += pWeapen->nCount;
				pWeapen->nCount = 0;
			}
			else
			{
				pWeapen->nCount -= pWeapen->nMaxAmmo - pWeapen->nCurAmmo;
				pWeapen->nCurAmmo = pWeapen->nMaxAmmo;
			}
		}
	}
}

// 绘制状态栏
void CMainFrame::DrawBar( CDC* pdc, int x, int y )
{
	int nST = m_nST % 10;

	switch( nST )
	{
	case GAME_ST_START:
		{
			// 开始态
			// 绘制开始画面
			pdc->BitBlt( x,y,SCREEN_W,SCREEN_H,m_pTitleDC,0,0,SRCCOPY );
			switch( m_nCurButton )
			{
			case 1:    // 鼠标落在“新的游戏”按钮上
				pdc->BitBlt( BUTTON_NEW_X+x,BUTTON_NEW_Y+y,BUTTON_NEW_W,BUTTON_NEW_H,m_pButtonsDC,0,0,SRCCOPY );
				break;
			case 2:    // 鼠标落在“读取进度”按钮上
				pdc->BitBlt( BUTTON_LOAD_X+x,BUTTON_LOAD_Y+y,BUTTON_LOAD_W,BUTTON_LOAD_H,m_pButtonsDC,0,39,SRCCOPY );
				break;
			case 3:    // 鼠标落在“退出游戏”按钮上
				pdc->BitBlt( BUTTON_EXIT_X+x,BUTTON_EXIT_Y+y,BUTTON_EXIT_W,BUTTON_EXIT_H,m_pButtonsDC,0,78,SRCCOPY );
				break;
			}
		}
		break;
	case GAME_ST_DIALOG:
	case GAME_ST_WALK:
	case GAME_ST_FIGHT:
		{
			// 绘制状态栏背景
			pdc->BitBlt( STATUS_BAR_X+x,STATUS_BAR_Y+y,STATUS_BAR_W,STATUS_BAR_H,m_pBarDC,0,0,SRCCOPY );
			// 根据武器状况绘制武器
			PaintGun1 (pdc, x, y, (1 == m_nCurWeapen));
			PaintGun2 (pdc, x, y, (2 == m_nCurWeapen));
			PaintGun3 (pdc, x, y, (3 == m_nCurWeapen));
			PaintGun4 (pdc, x, y, (4 == m_nCurWeapen));

			// 根据主角属性绘制生命条和经验条
			int nLife  = m_pGameMap->GetHeroLife();
			int nLevel = m_pGameMap->GetHeroLevel();
			int nExp   = m_pGameMap->GetHeroExp();
			
			if( m_nLevelUpCounter > 0 )
			{
				// 绘制升级动画
				if( m_nLevelUpCounter % 2 )
				{
					// 1>绘制金色的，闪烁的“Level UP”
					TransBlt( pdc->GetSafeHdc(), LABEL_LEVEL_UP_X+x,LABEL_LEVEL_UP_Y+y,LABEL_LEVEL_UP_W,LABEL_LEVEL_UP_H, 
					m_pButtonsDC->GetSafeHdc(), 0,147, COLORKEY );
					// 2>绘制金色的，闪烁的生命条和经验条
					pdc->StretchBlt( BUTTON_LIFE_X+x,BUTTON_LIFE_Y+y,nLife*BUTTON_LIFE_W/100,BUTTON_LIFE_H,m_pButtonsDC,33,117,1,BUTTON_LIFE_H,SRCCOPY );
					pdc->StretchBlt( BUTTON_EXP_X+x,BUTTON_EXP_Y+y,nLevel*BUTTON_EXP_W/100,BUTTON_EXP_H,m_pButtonsDC,33,117,1,BUTTON_EXP_H,SRCCOPY );
				}
				// 3>减少计数值
				m_nLevelUpCounter --;
			}
			else
			{
				// 正常绘制
				pdc->StretchBlt( BUTTON_LIFE_X+x,BUTTON_LIFE_Y+y,nLife*BUTTON_LIFE_W/100,BUTTON_LIFE_H,m_pButtonsDC,22,117,1,BUTTON_LIFE_H,SRCCOPY );
				pdc->StretchBlt( BUTTON_EXP_X+x,BUTTON_EXP_Y+y,nLevel*BUTTON_EXP_W/100,BUTTON_EXP_H,m_pButtonsDC,11,117,1,BUTTON_EXP_H,SRCCOPY );
				pdc->StretchBlt( BUTTON_EXP_X+x,BUTTON_EXP_Y+y,nExp*BUTTON_EXP_W/100,BUTTON_EXP_H,m_pButtonsDC,0,117,1,BUTTON_EXP_H,SRCCOPY );
			}
			// 鼠标落在“退出游戏”按钮上
			if (m_nCurButton == 3) {
				pdc->BitBlt( BUTTON_EXIT_X+x,BUTTON_EXIT_Y+y,BUTTON_EXIT_W,BUTTON_EXIT_H,m_pButtonsDC,0,78,SRCCOPY );
			}
		}
		break;
	}
}

void CMainFrame::PaintGun1( CDC* pdc, int x, int y, BOOL bCur )
{
	if( !m_stGun1.bValid )
		return;
	
	if( !bCur )
		pdc->BitBlt( BUTTON_GUN1_X+x,BUTTON_GUN1_Y+y,BUTTON_GUN1_W,69,m_pButtonsDC,129,0,SRCCOPY );
	else
		pdc->BitBlt( BUTTON_GUN1_X+x,BUTTON_GUN1_Y+y,BUTTON_GUN1_W,69,m_pButtonsDC,258,0,SRCCOPY );
	
	// 绘制弹夹内的子弹
	int nVoidBullet = m_stGun1.nMaxAmmo - m_stGun1.nCurAmmo;
	int nVB1 = nVoidBullet / 2;
	int nVB2 = nVoidBullet - nVB1;
	int w = 6;
	int h1 = 3 * nVB1;
	int h2 = 3 * nVB2;
	int x1 = BUTTON_GUN1_X + 92 + x;
	int x2 = BUTTON_GUN1_X + 99 + x;
	int y1 = BUTTON_GUN1_Y + 47 - h1 + y;
	int y2 = BUTTON_GUN1_Y + 47 - h2 + y;
	pdc->BitBlt( x1,y1,w,h1,pdc,0,0,WHITENESS );
	pdc->BitBlt( x2,y2,w,h2,pdc,0,0,WHITENESS );
	// 绘制子弹数目
	char temp[16];
	if( m_stGun1.nCount == -1 )
		sprintf( temp, "%s", "无限" );
	else
		sprintf( temp, "%6d", m_stGun1.nCount );
	pdc->TextOut( BUTTON_GUN1_X+50+x,BUTTON_GUN1_Y+52+y,temp );
}

void CMainFrame::PaintGun2( CDC* pdc, int x, int y, BOOL bCur )
{
	if( !m_stGun2.bValid )
		return;
	
	if( !bCur )
		pdc->BitBlt( BUTTON_GUN2_X+x,BUTTON_GUN2_Y+y,BUTTON_GUN2_W,69,m_pButtonsDC,129,69,SRCCOPY );
	else
		pdc->BitBlt( BUTTON_GUN2_X+x,BUTTON_GUN2_Y+y,BUTTON_GUN2_W,69,m_pButtonsDC,258,69,SRCCOPY );
	
	// 绘制弹夹内的子弹
	int nVoidBullet = m_stGun2.nMaxAmmo - m_stGun2.nCurAmmo;
	int nVB1 = nVoidBullet / 2;
	int nVB2 = nVoidBullet - nVB1;
	int w = 6;
	int h1 = 3 * nVB1;
	int h2 = 3 * nVB2;
	int x1 = BUTTON_GUN2_X + 92 + x;
	int x2 = BUTTON_GUN2_X + 99 + x;
	int y1 = BUTTON_GUN2_Y + 47 - h1 + y;
	int y2 = BUTTON_GUN2_Y + 47 - h2 + y;
	pdc->BitBlt( x1,y1,w,h1,pdc,0,0,WHITENESS );
	pdc->BitBlt( x2,y2,w,h2,pdc,0,0,WHITENESS );
	// 绘制子弹数目
	char temp[128];
	if( m_stGun2.nCount == -1 )
		sprintf( temp, "%s", "无限" );
	else
		sprintf( temp, "%6d", m_stGun2.nCount );
	pdc->TextOut( BUTTON_GUN2_X+50+x,BUTTON_GUN2_Y+52+y,temp );
}

void CMainFrame::PaintGun3( CDC* pdc, int x, int y, BOOL bCur )
{
	if( !m_stGun3.bValid )
		return;

	if( !bCur )
		pdc->BitBlt( BUTTON_GUN3_X+x,BUTTON_GUN3_Y+y,BUTTON_GUN3_W,69,m_pButtonsDC,129,138,SRCCOPY );
	else
		pdc->BitBlt( BUTTON_GUN3_X+x,BUTTON_GUN3_Y+y,BUTTON_GUN3_W,69,m_pButtonsDC,258,138,SRCCOPY );
	
	// 绘制弹夹内的子弹
	int i;
	int w = 3;
	int h;
    int tx;
    int ty;
	int left = BUTTON_GUN3_X + 91 + x;
	int top  = BUTTON_GUN3_Y + 11 + y;
	for( i=0; i<10; i++ )
	{
		int nVoidBullet = ((i+1) * 10 - m_stGun3.nCurAmmo);
		if( nVoidBullet < 0 )
			continue;
		if( nVoidBullet > 10 )
			nVoidBullet = 10;
		h = nVoidBullet * 3;
		tx = left + (i * 3);
		ty = top + 30 - h;

		pdc->BitBlt( tx,ty,w,h,pdc,0,0,WHITENESS );
	}
	// 绘制子弹数目
	char temp[128];
	if( m_stGun3.nCount == -1 )
		sprintf( temp, "%s", "无限" );
	else
		sprintf( temp, "%6d", m_stGun3.nCount );
	pdc->TextOut( BUTTON_GUN3_X+50+x,BUTTON_GUN3_Y+52+y,temp );
}

void CMainFrame::PaintGun4( CDC* pdc, int x, int y, BOOL bCur )
{
	if( !m_stGun4.bValid )
		return;
	
	if( !bCur )
		pdc->BitBlt( BUTTON_GUN4_X+x,BUTTON_GUN4_Y+y,BUTTON_GUN4_W,69,m_pButtonsDC,129,207,SRCCOPY );
	else
		pdc->BitBlt( BUTTON_GUN4_X+x,BUTTON_GUN4_Y+y,BUTTON_GUN4_W,69,m_pButtonsDC,258,207,SRCCOPY );
	
	// 绘制弹夹内的子弹
	if( m_stGun4.nCurAmmo == 0 )
    {
	    int w = 14;
	    int h = 6;
	    x += BUTTON_GUN4_X + 84;
	    y += BUTTON_GUN4_Y + 22;
	    pdc->BitBlt( x,y,w,h,pdc,0,0,WHITENESS );
    }

	// 绘制子弹数目
	char temp[128];
	if( m_stGun4.nCount == -1 )
		sprintf( temp, "%s", "无限" );
	else
		sprintf( temp, "%3d", m_stGun4.nCount );
	pdc->TextOut( BUTTON_GUN4_X+50+x,BUTTON_GUN4_Y+52+y,temp );
}

// 绘制子弹击中物体的效果
void CMainFrame::DrawBullets( CDC* pdc, int x, int y )
{
	// 绘制从角色到目标的黄线
	HANDLE hOldPen = pdc->SelectObject( CreatePen( PS_SOLID, 1, RGB(255,255,0)) );

	int hero_x, hero_y, hero_w, hero_h;
	m_pGameMap->m_pHero->GetHitRect( &hero_x, &hero_y, &hero_w, &hero_h );

	// 计算枪口位置
	int map_left = m_pGameMap->m_nLeft;
	int map_top  = m_pGameMap->m_nTop;
	int gun_x = hero_x - map_left + x;
	int gun_y = hero_y - map_top  + y;

	int xa = x;  //	子弹直射的目标点
    int ya = y;

	int nHeroStatus = m_pGameMap->m_pHero->m_nStatus;
	int nStatus = nHeroStatus % 20;
	if( (nStatus > 0) && (nStatus < 4) )
	{
		// 向上发射子弹
		gun_x += 6;
		gun_y -= 5;
		xa = gun_x;
		ya = y;
	}
	else if( (nStatus > 3) && (nStatus < 7) )
	{
		// 向下发射子弹
		gun_x += 21;
		gun_y += 24;
		xa = gun_x;
		ya = GAME_AREA_H + 32 + y;
	}
	else if( (nStatus > 6) && (nStatus < 10) )
	{
		// 向左发射子弹
		gun_x += 5;
		gun_y += 10;
		xa = -32 + x;
		ya = gun_y;
	}
	else if( (nStatus > 9) && (nStatus < 13) )
	{
		// 向右发射子弹
		gun_x += 25;
		gun_y += 10;
		xa = GAME_AREA_W + x;
		ya = gun_y;
	}

	// 绘制火花
	BOOL bDraw = FALSE;  // 判断子弹路径是否被绘制过
	int nFrame;
	int nItem;
	for( nFrame=4; nFrame>0; nFrame-- )
	{
		for( nItem=0; nItem<4; nItem++ )
		{
			if( m_paBullet[nItem][0] == nFrame )
			{
				int tx = m_paBullet[nItem][1] + x;
				int ty = m_paBullet[nItem][2] + y;

				// 绘制射击线
				pdc->MoveTo( gun_x, gun_y );
				pdc->LineTo( tx, ty );

				// 绘制副角色的射击线
				if( m_pGameMap->m_pHero->HaveHero2() )
				{
					pdc->MoveTo( gun_x + HERO2_OFFSET_X, gun_y + HERO2_OFFSET_Y );
					pdc->LineTo( tx, ty );
				}

				// 绘制火花
				TransBlt( pdc->GetSafeHdc(), tx+BulletOffset_x[nItem]-10, ty+BulletOffset_y[nItem]-nFrame*2-10, 
					20, 20, m_pButtonsDC->GetSafeHdc(), 20*(nFrame-1), 127, COLORKEY );
				m_paBullet[nItem][0] ++;    // 推进到下一桢
				if( m_paBullet[nItem][0] == 5 )
					m_paBullet[nItem][0] = 0;   // 动画完结

				bDraw = TRUE;
			}
		}
	}
	
	// 如果没有击中敌人，则子弹沿直线飞行
	if( !bDraw && (nHeroStatus > 40) && (nHeroStatus < 100) )
	{
		pdc->MoveTo( gun_x, gun_y );
		pdc->LineTo( xa, ya );

		// 绘制副角色的射击线
		if( m_pGameMap->m_pHero->HaveHero2() )
		{
			pdc->MoveTo( gun_x + HERO2_OFFSET_X, gun_y + HERO2_OFFSET_Y );
			pdc->LineTo( xa + HERO2_OFFSET_X, ya + HERO2_OFFSET_Y );
		}
	}

	DeleteObject( pdc->SelectObject( hOldPen ) );
}

// 绘制炮弹爆炸
void CMainFrame::DrawCannonBomb( CDC* pdc, int x, int y )
{
    if( m_paCannon[0] == 0 )
        return;

    // 绘制
	int map_left = m_pGameMap->m_nLeft;
	int map_top  = m_pGameMap->m_nTop;

    int tx = m_paCannon[2] - BOMB_IMG_H / 2 - map_left + x;
    int ty = m_paCannon[3] - BOMB_IMG_H / 2 - map_top  + y;
    int w = BOMB_IMG_W;
    int h = BOMB_IMG_H;
    int sx= (m_paCannon[0] - 1) / 2 * BOMB_IMG_W;
    int sy= 0;
	TransBlt( pdc->GetSafeHdc(), tx, ty, w, h, m_pBombDC->GetSafeHdc(), sx, sy, COLORKEY );

    // 推进到下一桢
    m_paCannon[0] ++;
    if( m_paCannon[0] == 21 )
    {
        // 动画完结
        m_paCannon[0] = 0;
        return;
    }

    // 调整动画的位置
    switch( m_paCannon[1] )
    {
    case HERO_DIRECTION_UP:     m_paCannon[3] -= 16;    break;
    case HERO_DIRECTION_DOWN:   m_paCannon[3] += 16;    break;
    case HERO_DIRECTION_LEFT:   m_paCannon[2] -= 16;    break;
    case HERO_DIRECTION_RIGHT:  m_paCannon[2] += 16;    break;
    }
}

// 升级（生命条和经验条背景变成金色，并显示“Level UP”）
void CMainFrame::LevelUp()
{
	// 播放升级的声音
	m_pMidi->PlayWave( FILENAME_WAV_LEVEL_UP );

	// 将升级动画计数器修改为1
	m_nLevelUpCounter = 20;
}

// 角色死亡
void CMainFrame::HeroDead()
{
	// 播放哀乐
	m_pMidi->PlayMidi( FILENAME_MIDI_DEAD );

	// 延时，回到开始画面
	::Sleep( 3000 );
	m_nST = GAME_ST_START;
}

// 鼠标左键按下
void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point)
{
    int x = point.x;
    int y = point.y;

    // 全屏幕模式下进行坐标调整
    if( m_bDDrawOK )
    {
		x -= (m_rcDDrawWindow.Width()  - SCREEN_W) / 2;
		y -= (m_rcDDrawWindow.Height() - SCREEN_H) / 2;
    }

	// 对话栏打开状态，只处理关闭对话栏的操作和退出程序的操作
	if (m_nST > 10)
	{
		// 对话态处理对话栏的点击关闭
		if( PtInArea(x, y, BUTTON_EXIT_X, BUTTON_EXIT_Y, BUTTON_EXIT_W, BUTTON_EXIT_H) )
		{
			m_pMidi->PlayWave( FILENAME_WAV_KEYPRESS );
			QuitGame();
			return;
		}

		// 必须在延时完成后才能响应Next按钮
		if( m_nMessageDelay == 0 )
		{
			// 点击“Next”图标，或对话框范围，都可以执行next操作
			if (PtInArea(x, y, BUTTON_NEXT_X, BUTTON_NEXT_Y, BUTTON_NEXT_W, BUTTON_NEXT_H)
				|| PtInArea(x, y, DIALOG_X, DIALOG_Y, DIALOG_W, DIALOG_H))
			{
				CloseDialog();
				// 通知事件处理函数继续执行脚本
				PostMessage( ID_GAME_MESSAGE, COMMAND_DIALOG, 0 );
			}
		}

		return;
	}

	int nST = m_nST % 10;
	switch( nST )
	{
	case GAME_ST_START:
		{
			// 开始态，处理状态栏的三个按钮
			if( PtInArea(x, y, BUTTON_NEW_X, BUTTON_NEW_Y, BUTTON_NEW_W, BUTTON_NEW_H) )
			{
				m_pMidi->PlayWave( FILENAME_WAV_KEYPRESS );
				InitGame();
			}
			else if( PtInArea(x, y, BUTTON_LOAD_X, BUTTON_LOAD_Y, BUTTON_LOAD_W, BUTTON_LOAD_H) )
			{
				m_pMidi->PlayWave( FILENAME_WAV_KEYPRESS );
				LoadGame();
			}
			else if( PtInArea(x, y, BUTTON_EXIT_X, BUTTON_EXIT_Y, BUTTON_EXIT_W, BUTTON_EXIT_H) )
			{
				m_pMidi->PlayWave( FILENAME_WAV_KEYPRESS );
				QuitGame();
			}
		}
		break;
		// 对话态也处理状态栏的各按钮，所以此处无break语句
	case GAME_ST_WALK:
	case GAME_ST_FIGHT:
		{
			// 行走态和战斗态，处理武器按钮和“退出游戏”按钮
			if( PtInArea(x, y, BUTTON_GUN1_X, BUTTON_GUN1_Y, BUTTON_GUN1_W, BUTTON_GUN1_H) )
			{
				if( (m_nCurWeapen != WEAPEN_GUN1) && m_stGun1.bValid )
				{
					m_nCurWeapen = WEAPEN_GUN1;
					m_weapon_change = TRUE;
					if (m_stGun1.nCount != 0) {
					m_pMidi->PlayWave( FILENAME_WAV_CHANGE_GUN );
					}
				}
			}
			else if( PtInArea(x, y, BUTTON_GUN2_X, BUTTON_GUN2_Y, BUTTON_GUN2_W, BUTTON_GUN2_H) )
			{
				if( (m_nCurWeapen != WEAPEN_GUN2) && m_stGun2.bValid )
				{
					m_nCurWeapen = WEAPEN_GUN2;
					m_weapon_change = TRUE;
					if (m_stGun2.nCount != 0) {
					m_pMidi->PlayWave( FILENAME_WAV_CHANGE_GUN );
					}
				}
			}
			else if( PtInArea(x, y, BUTTON_GUN3_X, BUTTON_GUN3_Y, BUTTON_GUN3_W, BUTTON_GUN3_H) )
			{
				if( (m_nCurWeapen != WEAPEN_GUN3) && m_stGun3.bValid )
				{
					m_nCurWeapen = WEAPEN_GUN3;
					m_weapon_change = TRUE;
					if (m_stGun3.nCount != 0) {
					m_pMidi->PlayWave( FILENAME_WAV_CHANGE_GUN );
					}
				}
			}
			else if( PtInArea(x, y, BUTTON_GUN4_X, BUTTON_GUN4_Y, BUTTON_GUN4_W, BUTTON_GUN4_H) )
			{
				if( (m_nCurWeapen != WEAPEN_GUN4) && m_stGun4.bValid )
				{
					m_nCurWeapen = WEAPEN_GUN4;
					m_weapon_change = TRUE;
					if (m_stGun4.nCount != 0) {
					m_pMidi->PlayWave( FILENAME_WAV_CHANGE_GUN );
					}
				}
			}
		}
		// 注意：此处无break！
	case GAME_ST_DIALOG:
		// 判断是否点击退出按钮
		if( PtInArea(x, y, BUTTON_EXIT_X, BUTTON_EXIT_Y, BUTTON_EXIT_W, BUTTON_EXIT_H) )
		{
			m_pMidi->PlayWave( FILENAME_WAV_KEYPRESS );
			QuitGame();
		}
		break;
	}
}

void CMainFrame::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// 对话栏打开状态，只处理关闭对话栏的操作
	if (m_nST > 10)
		return;

	// 全屏幕模式下进行坐标调整
    if( m_bDDrawOK )
    {
		point.x -= (m_rcDDrawWindow.Width()  - SCREEN_W) / 2;
		point.y -= (m_rcDDrawWindow.Height() - SCREEN_H) / 2;
    }

	if (! InGameRect(point)) {
		if (point.x > GAME_AREA_W) {//在按钮区，左右键功能相同
			OnLButtonDown(nFlags, point);
		}
		return;
	}

	m_mouse_pointer = point;
}

void CMainFrame::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// 对话栏打开状态，只处理关闭对话栏的操作
	if (m_nST > 10)
		return;

	// 左键双击，换武器
	int nOldWeapon = m_nCurWeapen;
	ChangeWeapon();
	if (nOldWeapon != m_nCurWeapen) {
		m_weapon_change = TRUE;
	}
}

void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
{
	// 全屏幕模式下进行坐标调整
	if (m_bDDrawOK) {
		point.x -= (m_rcDDrawWindow.Width()  - SCREEN_W) / 2;
		point.y -= (m_rcDDrawWindow.Height() - SCREEN_H) / 2;
	}

	int nST = m_nST % 10;
	switch( nST )
	{
	case GAME_ST_START:
		{
			// 开始态，处理状态栏的三个按钮
			if( PtInArea(point.x, point.y, BUTTON_NEW_X, BUTTON_NEW_Y, BUTTON_NEW_W, BUTTON_NEW_H) )
				m_nCurButton = 1;
			else if( PtInArea(point.x, point.y, BUTTON_LOAD_X, BUTTON_LOAD_Y, BUTTON_LOAD_W, BUTTON_LOAD_H) )
				m_nCurButton = 2;
			else if( PtInArea(point.x, point.y, BUTTON_EXIT_X, BUTTON_EXIT_Y, BUTTON_EXIT_W, BUTTON_EXIT_H) )
				m_nCurButton = 3;
			else
				m_nCurButton = 0;
		}
		break;
	case GAME_ST_DIALOG:
	case GAME_ST_WALK:
	case GAME_ST_FIGHT:
		{
			// 对话态，行走态和战斗态，只处理“退出游戏”按钮
			if( PtInArea(point.x, point.y, BUTTON_EXIT_X, BUTTON_EXIT_Y, BUTTON_EXIT_W, BUTTON_EXIT_H) )
				m_nCurButton = 3;
			else
				m_nCurButton = 0;
		}
		break;
	}

	m_mouse_pointer = point;

	//战斗态、自由态，随着鼠标的位置转动Hero的朝向
	if (nST == GAME_ST_WALK || nST == GAME_ST_FIGHT)
	{
		if(InHeroRect(point)){
			//中间位置，状态不变
		}
		else{
			// 如果没有方向键按下，才用鼠标控制转向
			if (GetAsyncKeyState(VK_UP)    || GetAsyncKeyState('W') ||
				GetAsyncKeyState(VK_DOWN)  || GetAsyncKeyState('S') ||
				GetAsyncKeyState(VK_LEFT)  || GetAsyncKeyState('A') ||
				GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState('D'))
			{
				// 有方向键按下
			}
			else
			{
				m_mouse_azimuth = InWhichArea(point);
			}
		}
	}

	CFrameWnd::OnMouseMove(nFlags, point);
}

BOOL CMainFrame::InHeroRect(CPoint pt)
{
	const int w = 32;
	const int h = 32;
	int center_x = GAME_AREA_W / 2;
	int center_y = GAME_AREA_H / 2;

	CRect rc(center_x - w / 2,
			 center_y - h / 2,
			 center_x + w / 2,
			 center_y + h / 2);
	return PtInRect(&rc, pt);
}

BOOL CMainFrame::InGameRect(CPoint pt)
{
	CRect rc(0, 0, GAME_AREA_W, GAME_AREA_H);
	return PtInRect(&rc, pt);
}

int CMainFrame::InWhichArea(CPoint pt)
{
	if (! InGameRect(pt)) {
		return 0;
	}

	int center_x = GAME_AREA_W / 2;
	int center_y = GAME_AREA_H / 2;
	int azimuth = 0;
	if((pt.x<center_x)&&(pt.y<center_y))
	{//左上区
		int dx=(center_x-pt.x);
		int dy=(center_y-pt.y);
		if((dx-dy)>dy)
			azimuth = DIRECTION_LEFT;
		else if((dy-dx)>dx)
			azimuth = DIRECTION_UP;
		else
			azimuth = DIRECTION_UP;
	}
	if((pt.x>center_x)&&(pt.y<center_y))
	{//右上区
		int dx=(pt.x-center_x);
		int dy=(center_y-pt.y);
		if((dx-dy)>dy)
			azimuth = DIRECTION_RIGHT;
		else if((dy-dx)>dx)
			azimuth = DIRECTION_UP;
		else
			azimuth = DIRECTION_UP;
	}
	if((pt.x<center_x)&&(pt.y>center_y))
	{//左下区
		int dx=(center_x-pt.x);
		int dy=(pt.y-center_y);
		if((dx-dy)>dy)
			azimuth = DIRECTION_LEFT;
		else if((dy-dx)>dx)
			azimuth = DIRECTION_DOWN;
		else
			azimuth = DIRECTION_DOWN;
	}
	if((pt.x>center_x)&&(pt.y>center_y))
	{//右下区
		int dx=(pt.x-center_x);
		int dy=(pt.y-center_y);
		if((dx-dy)>dy)
			azimuth = DIRECTION_RIGHT;
		else if((dy-dx)>dx)
			azimuth = DIRECTION_DOWN;
		else
			azimuth = DIRECTION_DOWN;
	}
	return azimuth;
}

BOOL CMainFrame::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	return 0;//告诉MFC已经设置好了光标，不要再设置一次了
}

// 屏幕从黑色背景中淡出
void CMainFrame::OpenScreen()
{
	m_bScreenClosed = FALSE;

    int x, y, w, h, scr_w, scr_h;
    if( m_bDDrawOK )
    {
		scr_w = m_rcDDrawWindow.Width();
		scr_h = m_rcDDrawWindow.Height();
        x = (scr_w - SCREEN_W) / 2;
        y = (scr_h - SCREEN_H) / 2;
        MakeDirectBuffer();
    }
    else
    {
        x = 0;
        y = 0;
        scr_w = SCREEN_W;
        scr_h = SCREEN_H;
        MakeBuffer();
    }

    w = GAME_AREA_W;
    h = GAME_AREA_H;

	CDC* pdc = GetDC();

	CDC TempDC;
	TempDC.CreateCompatibleDC( pdc );
    CBitmap bmp;
	bmp.CreateCompatibleBitmap( pdc, scr_w, scr_h );
    DeleteObject( TempDC.SelectObject( &bmp ) );

	TempDC.BitBlt( 0,0,scr_w,scr_h,m_pBufDC,0,0,SRCCOPY );

	BLENDFUNCTION bf;
	bf.AlphaFormat = 0;
	bf.BlendFlags = 0;
	bf.BlendOp = AC_SRC_OVER;
	for( bf.SourceConstantAlpha=0; bf.SourceConstantAlpha<200; bf.SourceConstantAlpha+=20 )
	{
		AlphaBlend( TempDC.GetSafeHdc(), x,y,w,h, m_pBufDC->GetSafeHdc(), x,y,w,h, bf );

        if( m_bDDrawOK )
            DirectPaint(&TempDC);
        else
		    pdc->BitBlt( 0,0,scr_w,scr_h, &TempDC, 0,0, SRCCOPY );

        Sleep(20);
	}

    ReleaseDC( pdc );
}

// 屏幕暗下变成黑色背景
void CMainFrame::CloseScreen()
{
    int x, y, w, h, scr_w, scr_h;
    if( m_bDDrawOK )
    {
		scr_w = m_rcDDrawWindow.Width();
		scr_h = m_rcDDrawWindow.Height();
        x = (scr_w - SCREEN_W) / 2;
        y = (scr_h - SCREEN_H) / 2;
    }
    else
    {
        x = 0;
        y = 0;
        scr_w = SCREEN_W;
        scr_h = SCREEN_H;
    }

    w = GAME_AREA_W;
    h = GAME_AREA_H;

	CDC* pdc = GetDC();

	CDC TempDC;
	TempDC.CreateCompatibleDC( pdc );
    CBitmap bmp;
	bmp.CreateCompatibleBitmap( pdc, scr_w, scr_h );
    DeleteObject( TempDC.SelectObject( &bmp ) );

	TempDC.BitBlt( 0,0,scr_w,scr_h,m_pBufDC,0,0,SRCCOPY );

	m_bScreenClosed = TRUE;
    if( m_bDDrawOK )
    {
        MakeDirectBuffer();
    }
    else
    {
        MakeBuffer();
    }

	BLENDFUNCTION bf;
	bf.AlphaFormat = 0;
	bf.BlendFlags = 0;
	bf.BlendOp = AC_SRC_OVER;
	for( bf.SourceConstantAlpha=0; bf.SourceConstantAlpha<200; bf.SourceConstantAlpha+=20 )
	{
		AlphaBlend( TempDC.GetSafeHdc(), x,y,w,h, m_pBufDC->GetSafeHdc(), x,y,w,h, bf );

        if( m_bDDrawOK )
            DirectPaint(&TempDC);
        else
		    pdc->BitBlt( 0,0,scr_w,scr_h, &TempDC, 0,0, SRCCOPY );

        Sleep(20);
	}

    ReleaseDC( pdc );
}

// 震动画面
void CMainFrame::ShakeScreen()
{
    CDC* pdc = GetDC();

    if( !m_bDDrawOK )
    {
	    int a, b;
	    int i;
	    for( i=0; i<10; i++ )
	    {
		    a=0;b=0;
		    pdc->BitBlt(0,0,GAME_AREA_W,GAME_AREA_H,m_pBufDC,a,b,SRCCOPY);
		    ::Sleep(20);
		    a=-16;b=-8;
		    pdc->BitBlt(0,0,GAME_AREA_W,GAME_AREA_H,m_pBufDC,a,b,SRCCOPY);
		    ::Sleep(20);
		    a=0;b=0;
		    pdc->BitBlt(0,0,GAME_AREA_W,GAME_AREA_H,m_pBufDC,a,b,SRCCOPY);
		    ::Sleep(20);
		    a=-16;b=8;
		    pdc->BitBlt(0,0,GAME_AREA_W,GAME_AREA_H,m_pBufDC,a,b,SRCCOPY);
		    ::Sleep(20);
	    }
	    pdc->BitBlt(0,0,GAME_AREA_W,GAME_AREA_H,m_pBufDC,0,0,SRCCOPY);
    }
    else
    {
        // DirectDraw的方法
		int scr_w = m_rcDDrawWindow.Width();
		int scr_h = m_rcDDrawWindow.Height();

	    CDC TempDC;
	    TempDC.CreateCompatibleDC( pdc );
        CBitmap bmp;
		bmp.CreateCompatibleBitmap( pdc, scr_w,scr_h );
        DeleteObject( TempDC.SelectObject( &bmp ) );
		TempDC.BitBlt( 0,0,scr_w,scr_h,m_pBufDC,0,0,SRCCOPY );

	    int a, b;
	    int i;
	    for( i=0; i<10; i++ )
	    {
		    a=0;b=0;
		    TempDC.BitBlt(0,0,scr_w,scr_h,m_pBufDC,a,b,SRCCOPY);
            DirectPaint(&TempDC);
		    ::Sleep(20);
		    a=-16;b=-8;
		    TempDC.BitBlt(0,0,scr_w,scr_h,m_pBufDC,a,b,SRCCOPY);
            DirectPaint(&TempDC);
		    ::Sleep(20);
		    a=0;b=0;
		    TempDC.BitBlt(0,0,scr_w,scr_h,m_pBufDC,a,b,SRCCOPY);
            DirectPaint(&TempDC);
		    ::Sleep(20);
		    a=-16;b=8;
		    TempDC.BitBlt(0,0,scr_w,scr_h,m_pBufDC,a,b,SRCCOPY);
            DirectPaint(&TempDC);
		    ::Sleep(20);
	    }

	    DirectPaint(m_pBufDC);
    }

  	ReleaseDC( pdc );
}

// 绘制对话栏
void CMainFrame::DrawDialog( CDC* pdc, int x, int y )
{
	// 1>从主缓冲区中复制出背景
	m_pDlgDC->BitBlt( 0,0,DIALOG_W,DIALOG_H, pdc, DIALOG_X+x,DIALOG_Y+y, SRCCOPY );

	// 2>绘制半透明的对话框衬底和边框
	HDC hdc = m_pDlgDC->GetSafeHdc();
	HDC hSrcDC = m_pButtonsDC->GetSafeHdc();

	BLENDFUNCTION bbf;
	bbf.AlphaFormat = 0;
	bbf.BlendFlags = 0;
	bbf.BlendOp = AC_SRC_OVER;
	bbf.SourceConstantAlpha = 200;
	AlphaBlend( hdc,10,0,DIALOG_W-20,10,hSrcDC,44,117,1,1,bbf );
	AlphaBlend( hdc,10,118,DIALOG_W-20,10,hSrcDC,44,117,1,1,bbf );
	AlphaBlend( hdc,0,0,10,128,hSrcDC,44,117,1,1,bbf );
	AlphaBlend( hdc,DIALOG_W-10,0,10,DIALOG_H,hSrcDC,44,117,1,1,bbf );
	bbf.SourceConstantAlpha = 150;
	AlphaBlend( hdc,10,10,DIALOG_W-20,108,hSrcDC,45,117,1,1,bbf );

	// 3>绘制文字（4行）
	// 3.1>首先绘制黑色的外框
	m_pDlgDC->SetTextColor(0x00000000);
	RECT rect;
    rect.left=50;
	rect.top=26;
	rect.right=DIALOG_W-50;
	rect.bottom=256;
	m_pDlgDC->DrawText( m_str1, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str2, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str3, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str4, 64, &rect, DT_LEFT );
    rect.left=49;
	rect.top=26;
	m_pDlgDC->DrawText( m_str1, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str2, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str3, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str4, 64, &rect, DT_LEFT );
    rect.left=51;
	rect.top=26;
	m_pDlgDC->DrawText( m_str1, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str2, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str3, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str4, 64, &rect, DT_LEFT );
    rect.left=50;
	rect.top=25;
	m_pDlgDC->DrawText( m_str1, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str2, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str3, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str4, 64, &rect, DT_LEFT );
    rect.left=50;
	rect.top=27;
	m_pDlgDC->DrawText( m_str1, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str2, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str3, 64, &rect, DT_LEFT );       rect.top += 20;
	m_pDlgDC->DrawText( m_str4, 64, &rect, DT_LEFT );
	// 3.2>生成一个文字区域是彩色线条，外面全部是黑色的图片
	CDC MaskDC;
	MaskDC.CreateCompatibleDC( m_pDlgDC );
	CFont font2;
	font2.CreateFont(16,0,0,0,400,FALSE,FALSE,0,
		GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"宋体");
	DeleteObject( MaskDC.SelectObject( &font2 ) );
	CBitmap bmpMask;
	bmpMask.CreateCompatibleBitmap( m_pDlgDC, DIALOG_W, 128 );
	DeleteObject( MaskDC.SelectObject( bmpMask ) );
	// 3.3>将MaskDC绘制成底色为黑色，文字为白色的黑白图片
	MaskDC.BitBlt( 0,0,DIALOG_W,128,&MaskDC,0,0,BLACKNESS );
	// 3.4>绘制黑的文字
	MaskDC.SetBkColor(0x00000000);//黑
	MaskDC.SetTextColor(0x00ffffff);//白
    rect.left=50;
	rect.top =26;
	rect.right=DIALOG_W-50;
	rect.bottom=128;
	MaskDC.DrawText( m_str1, 64, &rect, DT_LEFT );       rect.top += 20;
	MaskDC.DrawText( m_str2, 64, &rect, DT_LEFT );       rect.top += 20;
	MaskDC.DrawText( m_str3, 64, &rect, DT_LEFT );       rect.top += 20;
	MaskDC.DrawText( m_str4, 64, &rect, DT_LEFT );
	// 3.5>用“AND”的方式，在Mask上绘制Image
	MaskDC.BitBlt( 0,0,DIALOG_W,DIALOG_H, m_pRainbowDC, 0,0, SRCAND );
	// 3.6>两层或运算，叠加
	m_pDlgDC->BitBlt( 0,0,DIALOG_W,DIALOG_H, &MaskDC, 0,0, SRCPAINT );

	// 4>将组合好的对话栏写入目标设备
	pdc->BitBlt( DIALOG_X+x,DIALOG_Y+y,DIALOG_W,DIALOG_H, m_pDlgDC, 0,0, SRCCOPY );

#if 0
	// 绘制对话栏的边框
	int a1 = DIALOG_X;
	int b1 = DIALOG_Y - 128;
	int a2 = a1 + DIALOG_W;
	int b2 = b1 + DIALOG_H + 128;
	pdc->MoveTo( a1, b1 );
	pdc->LineTo( a2, b1 );
	pdc->LineTo( a2, b2 );
	pdc->LineTo( a1, b2 );
	pdc->LineTo( a1, b1 );
#endif

	// 5>绘制左边的头像（128 * 128）
	if( m_pLeftPhotoDC != NULL )
		TransBlt( pdc->GetSafeHdc(), DIALOG_X+x, DIALOG_Y-FACE_H+y, FACE_W, FACE_H, m_pLeftPhotoDC->GetSafeHdc(), 0, 0, COLORKEY );

	// 6>绘制右边的头像（128 * 128）
	if( m_pRightPhotoDC != NULL )
		TransBlt( pdc->GetSafeHdc(), DIALOG_X+DIALOG_W-FACE_W+x, DIALOG_Y-FACE_H+y, FACE_W, FACE_H, m_pRightPhotoDC->GetSafeHdc(), 0, 0, COLORKEY );

	// 7>绘制中间的物品（128 * 256）
	if( m_pItemPhotoDC != NULL )
		TransBlt( pdc->GetSafeHdc(), DIALOG_X+DIALOG_W/2-ITEM_W/2+x,DIALOG_Y-ITEM_H+y, ITEM_W, ITEM_H, m_pItemPhotoDC->GetSafeHdc(), 0, 0, COLORKEY );

	// 8>绘制“Next”小图标
	pdc->BitBlt( BUTTON_NEXT_X+x,BUTTON_NEXT_Y+y,BUTTON_NEXT_W,BUTTON_NEXT_H, m_pButtonsDC, 0,166, SRCCOPY );

	// 9>绘制颜色变化的图标边框
	HANDLE hOldPen;
	hOldPen = pdc->SelectObject( CreatePen(PS_SOLID, 3, RGB(255, m_nButtonNextColor, m_nButtonNextColor/2)) );

	int x1 = BUTTON_NEXT_X+x;
	int y1 = BUTTON_NEXT_Y+y;
	int x2 = x1 + BUTTON_NEXT_W;
	int y2 = y1 + BUTTON_NEXT_H;
	pdc->MoveTo( x1, y1 );
	pdc->LineTo( x2, y1 );
	pdc->LineTo( x2, y2 );
	pdc->LineTo( x1, y2 );
	pdc->LineTo( x1, y1 );

	// 释放画笔
	::DeleteObject( pdc->SelectObject(hOldPen) );

	// 10>改变Next边框的颜色
	if( m_nChangeColor == 0 )
	{
		// R值递增
		m_nButtonNextColor += 25;
		if( m_nButtonNextColor > 240 )
			m_nChangeColor = 1;
	}
	else
	{
		// R值递减
		m_nButtonNextColor -= 25;
		if( m_nButtonNextColor < 10 )
			m_nChangeColor = 0;
	}
}

// 显示对话栏
void CMainFrame::ShowDialog( int lface, int rface, int item, int file, int line )
{
	CDC* pdc = GetDC();

	// 打开左头像图片
	if( m_pLeftPhotoDC != NULL )
	{
		delete m_pLeftPhotoDC;
		m_pLeftPhotoDC = NULL;
	}
	if( lface != 0 )
	{
		m_pLeftPhotoDC = new CDC;
		m_pLeftPhotoDC->CreateCompatibleDC( pdc );
		if( !OpenBmpByID(m_pLeftPhotoDC, lface) )
		{
			delete m_pLeftPhotoDC;
			m_pLeftPhotoDC = NULL;
		}
	}

	// 打开右头像图片
	if( m_pRightPhotoDC != NULL )
	{
		delete m_pRightPhotoDC;
		m_pRightPhotoDC = NULL;
	}
	if( rface != 0 )
	{
		m_pRightPhotoDC = new CDC;
		m_pRightPhotoDC->CreateCompatibleDC( pdc );
		if( !OpenBmpByID(m_pRightPhotoDC, rface) )
		{
			delete m_pRightPhotoDC;
			m_pRightPhotoDC = NULL;
		}
	}
		
	// 打开物品图片
	if( m_pItemPhotoDC != NULL )
	{
		delete m_pItemPhotoDC;
		m_pItemPhotoDC = NULL;
	}
	if( item != 0 )
	{
		m_pItemPhotoDC = new CDC;
		m_pItemPhotoDC->CreateCompatibleDC( pdc );
		if( !OpenBmpByID(m_pItemPhotoDC, item) )
		{
			delete m_pItemPhotoDC;
			m_pItemPhotoDC = NULL;
		}
	}

	ReleaseDC( pdc );
	
	// 打开对话内容
	memset( m_str1, 0x20, sizeof(char)*64 );
	memset( m_str2, 0x20, sizeof(char)*64 );
	memset( m_str3, 0x20, sizeof(char)*64 );
	memset( m_str4, 0x20, sizeof(char)*64 );
	if( file != 0 )
		OpenDlgByID( file, line );

	// 修改状态号
	if( m_nST < 10 )
		m_nST += 10;
}

// 关闭对话栏
void CMainFrame::CloseDialog()
{
	// 播放按键声音
	m_pMidi->PlayWave( FILENAME_WAV_KEYPRESS );

	if( m_nST > 10 )
		m_nST -= 10;
}

// 根据ID号打开bmp文件创建HDC
BOOL CMainFrame::OpenBmpByID( CDC* pPhotoDC, int id )
{
	// 组合生成文件名
	char psFileName[256];
	sprintf( psFileName, "Img/%d.bmp", id );

	// 打开位图文件
	HBITMAP hbmp = (HBITMAP)LoadImage( NULL, psFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
	if( hbmp == NULL )
		return FALSE;

	DeleteObject( pPhotoDC->SelectObject( hbmp ) );
	return TRUE;
}

// 根据ID号和行号打开dlg文件，读出4行对话内容
BOOL CMainFrame::OpenDlgByID( int file, int line )
{
	// 组合生成文件名
	char psFileName[256];
	sprintf( psFileName, "Dlg/%d.dlg", file );

	HANDLE hFile;
	hFile = CreateFile( psFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, NULL );
	if( hFile==INVALID_HANDLE_VALUE )
		return FALSE;

	DWORD dwActualSize = 1;

	int index1 = 0;
	int index2 = 0;
	int index3 = 0;
	int index4 = 0;
	char c;
	int nCurLine = 1;
	//读出指定行的内容
	while( dwActualSize != 0 )
	{
		ReadFile(hFile,&c,sizeof(char),&dwActualSize,NULL);
		if( c == 0x0D )
		{	//windows下回车是由“0x0D、0x0A”构成的
			ReadFile( hFile, &c, sizeof(char), &dwActualSize, NULL );
			nCurLine ++;
		}
		else
		{
			if( nCurLine == line )
			{
				m_str1[index1] = c;
				if( index1<63 )
					index1 ++;
			}
			else if( nCurLine == (line+1) )
			{
				m_str2[index2] = c;
				if( index2<63 )
					index2 ++;
			}
			else if( nCurLine == (line+2) )
			{
				m_str3[index3] = c;
				if( index3<63 )
					index3 ++;
			}
			else if( nCurLine == (line+3) )
			{
				m_str4[index4] = c;
				if( index4<63 )
					index4 ++;
			}
		}
	}//while语句结束

	//关闭文件
	CloseHandle(hFile);

	return TRUE;
}

// 开始新的游戏
void CMainFrame::InitGame()
{
// 初始化武器设定
	m_nCurWeapen = WEAPEN_GUN1;       // 默认武器：冲锋枪

	m_stGun1.bValid   = FALSE;
	m_stGun1.nPower   = 2000;
	m_stGun1.nCurAmmo = 0;
	m_stGun1.nMaxAmmo = 30;
	m_stGun1.nCount   = -1;
    m_stGun1.lShootDelay = 50;
    m_stGun1.lRenewCassetteDelay = 300;

	m_stGun2.bValid   = FALSE;
	m_stGun2.nPower   = 15000;
	m_stGun2.nCurAmmo = 0;
	m_stGun2.nMaxAmmo = 30;
	m_stGun2.nCount   = 600;
    m_stGun2.lShootDelay = 100;
    m_stGun2.lRenewCassetteDelay = 1000;

	m_stGun3.bValid   = FALSE;
	m_stGun3.nPower   = 20000;
	m_stGun3.nCurAmmo = 0;
	m_stGun3.nMaxAmmo = 100;
	m_stGun3.nCount   = 3000;
    m_stGun3.lShootDelay = 120;
    m_stGun3.lRenewCassetteDelay = 1500;

	m_stGun4.bValid   = FALSE;
	m_stGun4.nPower   = 50000;
	m_stGun4.nCurAmmo = 0;
	m_stGun4.nMaxAmmo = 1;
	m_stGun4.nCount   = 0;
    m_stGun4.lShootDelay = 400;
    m_stGun4.lRenewCassetteDelay = 1500;

	m_pGameMap->m_pHero->m_nLife  = 1000;
	m_pGameMap->m_pHero->m_nLevel = 50;
	m_pGameMap->m_pHero->m_nExp   = 0;

	// 清除BOSS和NPC
	m_pGameMap->CleanBoss();
	m_pGameMap->CleanNpc();

	// 打开脚本
	m_pScript->OpenScript( 1 );
	ScriptProc();
}

// 读取进度
BOOL CMainFrame::LoadGame()
{
	CloseScreen();

	FILE* fp = fopen( FILENAME_GAME_SAVE, "r" );
	if( fp == NULL )
	{
		ShowCursor(TRUE);
		MessageBox( "读取游戏进度失败！\n请检查应用程序目录下的xyj.sav文件！",
			"提示信息", MB_ICONINFORMATION | MB_OK );
		ShowCursor(FALSE);
		return FALSE;
	}

	struct _SAVED stData;
	int ret = fread( &stData, sizeof(struct _SAVED), 1, fp );
	fclose( fp );
	if( ret != 1 )
	{
		ShowCursor(TRUE);
		MessageBox( "读取游戏进度失败！\n请检查应用程序目录下的xyj.sav文件！",
			"提示信息", MB_ICONINFORMATION | MB_OK );
		ShowCursor(FALSE);
		return FALSE;
	}

	// 更新m_pGameMap
	delete m_pGameMap;
	m_pGameMap = new CGameMap( this );

	memcpy( &m_stGun1, &stData.stWeapen[0], sizeof(struct _WEAPEN) );
	memcpy( &m_stGun2, &stData.stWeapen[1], sizeof(struct _WEAPEN) );
	memcpy( &m_stGun3, &stData.stWeapen[2], sizeof(struct _WEAPEN) );
	memcpy( &m_stGun4, &stData.stWeapen[3], sizeof(struct _WEAPEN) );
    m_nCurWeapen = stData.nCurWeapen;

	m_pGameMap->m_pHero->m_nLife   = stData.nLife;
	m_pGameMap->m_pHero->m_nLevel  = stData.nLevel;
	m_pGameMap->m_pHero->m_nExp    = stData.nExp;

	// 清除BOSS和NPC
	m_pGameMap->CleanBoss();
	m_pGameMap->CleanNpc();

	PostMessage( ID_GAME_MESSAGE, stData.nScript, 0 );

	return TRUE;
}

// 保存进度
BOOL CMainFrame::SaveGame( int nScript )
{
	FILE* fp = fopen( FILENAME_GAME_SAVE, "w" );
	if( fp == NULL )
	{
		ShowCursor(TRUE);
		MessageBox("存储游戏进度失败！\n本游戏需要在应用程序目录下生成xyj.sav文件，但这一操作失败了。",
			"提示信息", MB_ICONINFORMATION | MB_OK );
		ShowCursor(FALSE);
		return FALSE;
	}

	struct _SAVED stData;

	memcpy( &stData.stWeapen[0], &m_stGun1, sizeof(struct _WEAPEN) );
	memcpy( &stData.stWeapen[1], &m_stGun2, sizeof(struct _WEAPEN) );
	memcpy( &stData.stWeapen[2], &m_stGun3, sizeof(struct _WEAPEN) );
	memcpy( &stData.stWeapen[3], &m_stGun4, sizeof(struct _WEAPEN) );
    stData.nCurWeapen = m_nCurWeapen;

	stData.nLife   = m_pGameMap->m_pHero->m_nLife;
	stData.nLevel  = m_pGameMap->m_pHero->m_nLevel;
	stData.nExp    = m_pGameMap->m_pHero->m_nExp;

	stData.nScript = nScript;
	
	int ret = fwrite( &stData, sizeof(struct _SAVED), 1, fp );
	fclose( fp );
	if( ret != 1 )
	{
		ShowCursor(TRUE);
		MessageBox("存储游戏进度失败！\n本游戏需要在C应用程序目录下生成xyj.sav文件，但这一操作失败了。",
			"提示信息", MB_ICONINFORMATION | MB_OK );
		ShowCursor(FALSE);
		return FALSE;
	}

	return TRUE;
}

LRESULT CMainFrame::OnGameMessage( WPARAM type, LPARAM lParam )
{
	// 解读下一条命令
	// 有一些指令，如对话、行走、延时等，
	// 它们执行后不再执行下一条指令，而是等一会儿（行走、延时）才执行下一条指令，
	// 或者等待玩家响应后才执行下一条指令（DIALOG指令）
	if( m_nLastCommandType != 0 )
	{
		// 如果刚才执行的是DIALOG指令，则必须等待用户响应Next的操作。
		if( m_nLastCommandType == COMMAND_DIALOG )
		{
			if( type != COMMAND_DIALOG )
				return 0;
		}

		m_nLastCommandType = 0;
		// 继续执行脚本
		ScriptProc();
		return 0;
	}

	// 防止消息被连续触发
	if( m_nMessageDelay != 0 )
		return 0;

	// 打开事件对应的脚本
	if( m_pScript->OpenScript( type ) )
	{
		// 执行脚本
		ScriptProc();
	}
	else
	{
		// 没有对应脚本，返回开始画面

#ifdef _DEBUG
		char psInfo[256];
		sprintf( psInfo, "没有发现Spt/%d.spt文件，\n程序继续运行需要执行该脚本文件。\n程序将退出到开始画面。", type );
		ShowCursor(TRUE);
		MessageBox(psInfo, "脚本错误！", MB_ICONEXCLAMATION | MB_OK);
		ShowCursor(FALSE);
#endif
		m_pMidi->PlayMidi( "Snd/start.mid" );
		CloseScreen();
		m_nST = GAME_ST_START;

		// 清除BOSS和NPC
		m_pGameMap->CleanBoss();
		m_pGameMap->CleanNpc();

		OpenScreen();
	}

	return 0;
}

// 脚本处理
BOOL CMainFrame::ScriptProc()
{
	CString strCommand;
	while( m_pScript->PopCommand( strCommand ) )
	{
		// 判断是否是注释行
		if( strCommand.Left(1) == "#" )
			continue;

		// 读出命令头
		CString strHead;

		if( !GetSlice( strHead, strCommand, 0 ) )
		{
			OutputDebugString( "缺少命令头！\n" );
			return FALSE;
		}

		if( strHead == "OPEN_SCREEN" )
			OpenScreen();
		else if( strHead == "CLOSE_SCREEN" )
			CloseScreen();
		else if( strHead == "SHAKE_SCREEN" )
			ShakeScreen();
		else if( strHead == "PLAY_MIDI" )
			CmdPlayMidi( strCommand );
		else if( strHead == "STOP_MIDI" )
			m_pMidi->StopMidi();
		else if( strHead == "PLAY_WAV" )
			CmdPlayWav( strCommand );
		else if( strHead == "SHOW_BMP" )
			CmdShowBmp( strCommand );
		else if( strHead == "HIDE_BMP" )
			m_pBmp->Show( FALSE );
		else if( strHead == "SHOW_AVI" )
			CmdShowAvi( strCommand );
		else if( strHead == "HIDE_AVI" )
			CmdHideAvi( strCommand );
		else if( strHead == "DIALOG" )
		{
			CmdDialog( strCommand );
			m_nLastCommandType = COMMAND_DIALOG;
			m_nMessageDelay = COMMAND_DELAY_DIALOG;
			return TRUE;
		}
		else if( strHead == "DELAY" )
		{
			m_nLastCommandType = COMMAND_DELAY;
			CmdDelay( strCommand );
			return TRUE;
		}
		else if( strHead == "SET_GUN" )
			CmdSetGun( strCommand );
		else if( strHead == "ADD_GUN" )
			CmdAddGun( strCommand );
		else if( strHead == "DELETE_GUN" )
			CmdDeleteGun( strCommand );
		else if( strHead == "ADD_AMMO" )
			CmdAddAmmo( strCommand );
		else if( strHead == "SET_HERO_IMAGE" )
			CmdSetHeroImage( strCommand );
		else if( strHead == "SET_HERO_IMAGE2" )
			CmdSetHeroImage2( strCommand );
		else if( strHead == "SET_HERO_DIRECTION" )
			CmdSetHeroDirection( strCommand );
        else if( strHead == "CENTER_HERO" )
            CmdCenterHero();
		else if( strHead == "LEVEL_UP" )
			CmdLevelUp();
		else if( strHead == "RECOVER_LIFE" )
			m_pGameMap->m_pHero->m_nLife = 1000;
		else if( strHead == "KILL_HERO" )
			m_pGameMap->HitHero( 10000000 );  // 角色必死
		else if( strHead == "OPEN_MAP" )
			CmdOpenMap( strCommand );
		else if( strHead == "SET_MAP_LEFT_TOP" )
			CmdSetMapLeftTop( strCommand );
		else if( strHead == "SET_MAP_CENTER_GRIDE" )
			CmdSetMapCenterGride( strCommand );
		else if( strHead == "OPEN_SCRIPT" )
			CmdOpenScript( strCommand );
		else if( strHead == "SET_GAME_STATUS" )
			CmdSetGameStatus( strCommand );
		else if( strHead == "SET_MAP" )
			CmdSetMap( strCommand );
		else if( strHead == "SET_NPC" )
			CmdSetNpc( strCommand );
		else if( strHead == "ADD_NPC" )
			CmdAddNpc( strCommand );
		else if( strHead == "CLEAN_NPC" )
			m_pGameMap->CleanNpc();
		else if( strHead == "SET_BOSS" )
			CmdSetBoss( strCommand );
		else if( strHead == "CLEAN_BOSS" )
			m_pGameMap->CleanBoss();
		else if( strHead == "SAVE_GAME" )
			CmdSaveGame( strCommand );
		else
        {
            char temp[256];
            _snprintf( temp, 256, "无法处理的脚本指令！%s\n", strHead );

			OutputDebugString(temp);
#ifdef _DEBUG
			ShowCursor(TRUE);
            MessageBox(temp);
			ShowCursor(FALSE);
#endif
        }
	}

	// 全部脚本执行完成
	return TRUE;
}

// 循环播放Midi
BOOL CMainFrame::CmdPlayMidi( CString& strCommand )
{
	CString strFileName;
	if( !GetSlice( strFileName, strCommand, 1 ) )
	{
		OutputDebugString( "播放MIDI指令解析出错！\n" );
		return FALSE;
	}

	char psFileName[256];
	sprintf( psFileName, "Snd/%s", strFileName );

	m_pMidi->PlayMidi( psFileName );

	return TRUE;
}

// 播放音效
BOOL CMainFrame::CmdPlayWav( CString& strCommand )
{
	CString strFileName;
	if( !GetSlice( strFileName, strCommand, 1 ) )
	{
		OutputDebugString( "播放音效指令解析出错！\n" );
		return FALSE;
	}

	char psFileName[256];
	sprintf( psFileName, "Snd/%s", strFileName );

	m_pMidi->PlayWave( psFileName );

	return TRUE;
}

// 显示图片
BOOL CMainFrame::CmdShowBmp( CString& strCommand )
{
	// 图片显示指令
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString( "图片显示指令解析出错！\n" );
		return FALSE;
	}

	// 得到文件名
	char psFileName[256];
	sprintf( psFileName, "Img/%s", strTemp );

	// 得到x
	if( !GetSlice( strTemp, strCommand, 2 ) )
	{
		OutputDebugString( "图片显示指令解析出错！\n" );
		return FALSE;
	}
	int x = atoi( strTemp );

	// 得到y
	if( !GetSlice( strTemp, strCommand, 3 ) )
	{
		OutputDebugString( "图片显示指令解析出错！\n" );
		return FALSE;
	}
	int y = atoi( strTemp );

	// 得到sx
	if( !GetSlice( strTemp, strCommand, 4 ) )
	{
		// 没有后续参数，是整图显示
		// 执行命令
		if( !m_pBmp->Open( psFileName, x, y ) )
		{
			OutputDebugString( "图片显示指令解析出错！\n" );
			return FALSE;
		}

		return TRUE;
	}
	int sx = atoi( strTemp );

	// 得到sy
	if( !GetSlice( strTemp, strCommand, 5 ) )
	{
		OutputDebugString( "图片显示指令解析出错！\n" );
		return FALSE;
	}
	int sy = atoi( strTemp );

	// 得到sw
	if( !GetSlice( strTemp, strCommand, 6 ) )
	{
		OutputDebugString( "图片显示指令解析出错！\n" );
		return FALSE;
	}
	int sw = atoi( strTemp );

	// 得到sh
	if( !GetSlice( strTemp, strCommand, 7 ) )
	{
		OutputDebugString( "图片显示指令解析出错！\n" );
		return FALSE;
	}
	int sh = atoi( strTemp );

	// 执行命令
	if( !m_pBmp->Open( psFileName, x,y,sx,sy,sw,sh ) )
	{
		OutputDebugString( "图片显示指令解析出错！\n" );
		return FALSE;
	}

	return TRUE;
}

// 显示动画序列
BOOL CMainFrame::CmdShowAvi( CString& strCommand )
{
	// 动画显示指令
	CString strFileName;
	if( !GetSlice( strFileName, strCommand, 1 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}

	// 得到文件名
	char psFileName[256];
	sprintf( psFileName, "Img/%s", strFileName );

	// 得到Index
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 2 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nIndex = atoi( strTemp );

	if( (nIndex < 0) || (nIndex >= AVI_MAX) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}

	// 得到x
	if( !GetSlice( strTemp, strCommand, 3 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int x = atoi( strTemp );

	// 得到y
	if( !GetSlice( strTemp, strCommand, 4 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int y = atoi( strTemp );

	// 得到TileX
	if( !GetSlice( strTemp, strCommand, 5 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nTileX = atoi( strTemp );

	// 得到TileY
	if( !GetSlice( strTemp, strCommand, 6 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nTileY = atoi( strTemp );

	// 得到TileW
	if( !GetSlice( strTemp, strCommand, 7 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nTileW = atoi( strTemp );

	// 得到TileH
	if( !GetSlice( strTemp, strCommand, 8 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nTileH = atoi( strTemp );

	// 得到ArrayMode
	if( !GetSlice( strTemp, strCommand, 9 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nArrayMode = atoi( strTemp );

	// 得到TileCount
	if( !GetSlice( strTemp, strCommand, 10 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nTileCount = atoi( strTemp );

	// 得到CurTile
	if( !GetSlice( strTemp, strCommand, 11 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nCurTile = atoi( strTemp );

	// 得到Times
	if( !GetSlice( strTemp, strCommand, 12 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nTimes = atoi( strTemp );

	// 得到Interval
	if( !GetSlice( strTemp, strCommand, 13 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nInterval = atoi( strTemp );

	// 得到OverMode
	if( !GetSlice( strTemp, strCommand, 14 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nOverMode = atoi( strTemp );

	// 得到OffsetX
	if( !GetSlice( strTemp, strCommand, 15 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nOffsetX = atoi( strTemp );

	// 得到nOffsetY
	if( !GetSlice( strTemp, strCommand, 16 ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}
	int nOffsetY = atoi( strTemp );

	// 执行命令
	if( !m_pAvi[nIndex].Open( psFileName, x, y, nTileX, nTileY, nTileW, nTileH,
							  nArrayMode, nTileCount, nCurTile, nTimes, nInterval,
							  nOverMode, nOffsetX, nOffsetY ) )
	{
		OutputDebugString( "动画显示指令解析出错！\n" );
		return FALSE;
	}

	return TRUE;
}

// 隐藏动画序列
BOOL CMainFrame::CmdHideAvi( CString& strCommand )
{
	// 得到Index
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString( "隐藏动画指令解析出错！\n" );
		return FALSE;
	}
	int nIndex = atoi( strTemp );

	if( (nIndex < 0) || (nIndex >= AVI_MAX) )
	{
		OutputDebugString( "隐藏动画指令参数错误！\n" );
		return FALSE;
	}

	// 执行命令
	m_pAvi[nIndex].Show( FALSE );

	return TRUE;
}

// 显示对话栏
BOOL CMainFrame::CmdDialog( CString& strCommand )
{
	// 得到左头像代号
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("对话指令解析出错！\n");
		return FALSE;
	}
	int nLeft = atoi( strTemp );

	// 得到右头像代号
	if( !GetSlice( strTemp, strCommand, 2 ) )
	{
		OutputDebugString("对话指令解析出错！\n");
		return FALSE;
	}
	int nRight = atoi( strTemp );

	// 得到物品代号
	if( !GetSlice( strTemp, strCommand, 3 ) )
	{
		OutputDebugString("对话指令解析出错！\n");
		return FALSE;
	}
	int nItem = atoi( strTemp );

	// 得到对话文件代号
	if( !GetSlice( strTemp, strCommand, 4 ) )
	{
		OutputDebugString("对话指令解析出错！\n");
		return FALSE;
	}
	int nFile = atoi( strTemp );

	// 得到对话起始行号
	if( !GetSlice( strTemp, strCommand, 5 ) )
	{
		OutputDebugString("对话指令解析出错！\n");
		return FALSE;
	}
	int nLine = atoi( strTemp );

	// 执行命令
	ShowDialog( nLeft, nRight, nItem, nFile, nLine );

	return TRUE;
}

// 延时
BOOL CMainFrame::CmdDelay( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("延时指令解析出错！\n");
		return FALSE;
	}
	int nDelay = atoi( strTemp );

	// 延时时间大约是nDelay * 20毫秒
	m_nMessageDelay = nDelay;

	return TRUE;;
}

// 设置武器
BOOL CMainFrame::CmdSetGun( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("设置角色武器状态的指令解析出错！\n");
		return FALSE;
	}

	if( strTemp == "TRUE" )
		m_pGameMap->m_pHero->SetGun( TRUE );
	else if( strTemp == "FALSE" )
		m_pGameMap->m_pHero->SetGun( FALSE );
	else
	{
		OutputDebugString("设置角色武器状态的指令解析出错！\n");
		return FALSE;
	}

	return TRUE;
}

// 添加武器
BOOL CMainFrame::CmdAddGun( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("添加武器指令解析出错！\n");
		return FALSE;
	}
	int nGunIndex = atoi( strTemp );
	switch( m_nCurWeapen )
	{
	case WEAPEN_GUN1:
		if (! m_stGun1.bValid) {
			m_nCurWeapen = 0;
			m_stGun1.nCurAmmo = 0;
		}
		break;
	case WEAPEN_GUN2:
		if (! m_stGun2.bValid) {
			m_nCurWeapen = 0;
			m_stGun2.nCurAmmo = 0;
		}
		break;
	case WEAPEN_GUN3:
		if (! m_stGun3.bValid) {
			m_nCurWeapen = 0;
			m_stGun3.nCurAmmo = 0;
		}
		break;
	case WEAPEN_GUN4:
		if (! m_stGun4.bValid) {
			m_nCurWeapen = 0;
			m_stGun4.nCurAmmo = 0;
		}
		break;
	default:
		m_nCurWeapen = 0;
	}

	if( nGunIndex == 1 )
	{
		m_stGun1.bValid = TRUE;
		if (m_nCurWeapen < WEAPEN_GUN1) {
			m_nCurWeapen = WEAPEN_GUN1;
		}
	}
	else if(  nGunIndex == 2 )
	{
		m_stGun2.bValid = TRUE;
		if (m_nCurWeapen < WEAPEN_GUN2) {
			m_nCurWeapen = WEAPEN_GUN2;
		}
	}
	else if(  nGunIndex == 3 )
	{
		m_stGun3.bValid = TRUE;
		if (m_nCurWeapen < WEAPEN_GUN3) {
			m_nCurWeapen = WEAPEN_GUN3;
		}
	}
	else if(  nGunIndex == 4 )
	{
		m_stGun4.bValid = TRUE;
		if (m_nCurWeapen < WEAPEN_GUN4) {
			m_nCurWeapen = WEAPEN_GUN4;
		}
	}
	else
	{
		OutputDebugString("添加武器指令解析出错！\n");
		return FALSE;
	}

	return TRUE;
}

// 隐藏武器
BOOL CMainFrame::CmdDeleteGun( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("隐藏武器指令解析出错！\n");
		return FALSE;
	}
	int nGunIndex = atoi( strTemp );

	if( nGunIndex == 1 )
	{
		m_stGun1.bValid = FALSE;
		m_stGun1.nCount = 0;
		m_stGun1.nCurAmmo = 0;
	}
	else if(  nGunIndex == 2 )
	{
		m_stGun2.bValid = FALSE;
		m_stGun2.nCount = 0;
		m_stGun2.nCurAmmo = 0;
	}
	else if(  nGunIndex == 3 )
	{
		m_stGun3.bValid = FALSE;
		m_stGun3.nCount = 0;
		m_stGun3.nCurAmmo = 0;
	}
	else if(  nGunIndex == 4 )
	{
		m_stGun4.bValid = FALSE;
		m_stGun4.nCount = 0;
		m_stGun4.nCurAmmo = 0;
	}
	else
	{
		OutputDebugString("隐藏武器指令解析出错！\n");
		return FALSE;
	}

	return TRUE;
}

// 添加子弹
BOOL CMainFrame::CmdAddAmmo( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("添加子弹指令解析出错！\n");
		return FALSE;
	}
	int nGunIndex = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 2 ) )
	{
		OutputDebugString("添加子弹指令解析出错！\n");
		return FALSE;
	}
	int nAmmo = atoi( strTemp );

	if( nGunIndex == 1 )
	{
		if( nAmmo >= 99999 )  // 子弹无限
			m_stGun1.nCount = -1;
		else if( m_stGun1.nCount != -1 )
			m_stGun1.nCount += nAmmo;

		if (m_stGun1.bValid &&
			m_nCurWeapen < WEAPEN_GUN1) {
			m_nCurWeapen = WEAPEN_GUN1;
		}
	}
	else if(  nGunIndex == 2 )
	{
		if( nAmmo >= 99999 )  // 子弹无限
			m_stGun2.nCount = -1;
		else if( m_stGun2.nCount != -1 )
			m_stGun2.nCount += nAmmo;

		//优先使用威力更大的武器
		if (m_stGun2.bValid &&
			m_nCurWeapen < WEAPEN_GUN2) {
			m_nCurWeapen = WEAPEN_GUN2;
		}
	}
	else if(  nGunIndex == 3 )
	{
		if( nAmmo >= 99999 )  // 子弹无限
			m_stGun3.nCount = -1;
		else if( m_stGun3.nCount != -1 )
			m_stGun3.nCount += nAmmo;

		//优先使用威力更大的武器
		if (m_stGun3.bValid &&
			m_nCurWeapen < WEAPEN_GUN3) {
			m_nCurWeapen = WEAPEN_GUN3;
		}
	}
	else if(  nGunIndex == 4 )
	{
		if( nAmmo >= 99999 )  // 子弹无限
			m_stGun4.nCount = -1;
		else if( m_stGun4.nCount != -1 )
			m_stGun4.nCount += nAmmo;

		//优先使用威力更大的武器
		if (m_stGun4.bValid &&
			m_nCurWeapen < WEAPEN_GUN4) {
			m_nCurWeapen = WEAPEN_GUN4;
		}
	}
	else
	{
		OutputDebugString("添加子弹指令解析出错！\n");
		return FALSE;
	}

	return TRUE;
}

// 设置角色图片
BOOL CMainFrame::CmdSetHeroImage( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("设置角色图片指令解析出错！\n");
		return FALSE;
	}
	char psBmpFileName[256];
	sprintf( psBmpFileName, "Img/%s", strTemp );

	m_pGameMap->m_pHero->InitImage( psBmpFileName );

	return TRUE;
}

// 设置角色图片
BOOL CMainFrame::CmdSetHeroImage2( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("设置角色图片指令解析出错！\n");
		return FALSE;
	}
	char psBmpFileName[256];
	sprintf( psBmpFileName, "Img/%s", strTemp );

	m_pGameMap->m_pHero->InitImage2( psBmpFileName );

	return TRUE;
}

// 设置角色朝向
BOOL CMainFrame::CmdSetHeroDirection( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("设置角色朝向指令解析出错！\n");
		return FALSE;
	}
	
	int nDirection = 0;

	if( strTemp == "UP" )
		nDirection = HERO_DIRECTION_UP;
	else if( strTemp == "DOWN" )
		nDirection = HERO_DIRECTION_DOWN;
	else if( strTemp == "LEFT" )
		nDirection = HERO_DIRECTION_LEFT;
	else if( strTemp == "RIGHT" )
		nDirection = HERO_DIRECTION_RIGHT;

	if( !m_pGameMap->m_pHero->SetDirection(nDirection) )
	{
		OutputDebugString("设置角色朝向指令解析出错！\n");
		return FALSE;
	}

	return TRUE;
}

// 使角色位于地图的中心
BOOL CMainFrame::CmdCenterHero()
{
    int nLeft, nTop;
    if( !m_pGameMap->GetLeftTop(&nLeft, &nTop) )
        return FALSE;

	// 将角色放置在地图显示区域的中央
	m_pGameMap->m_pHero->SetPos( nLeft + 288, nTop + 192 );
	// 恢复角色的属性
	m_pGameMap->m_pHero->m_nStatus = 6;

    return TRUE;
}

// 角色提升一级
BOOL CMainFrame::CmdLevelUp()
{
	m_pGameMap->m_pHero->m_nLevel += 50;
	m_pGameMap->m_pHero->m_nLife = 1000;
	if( m_pGameMap->m_pHero->m_nLevel > 1000 )
		m_pGameMap->m_pHero->m_nLevel = 1000;

	LevelUp();

	return TRUE;
}

// 打开地图文件
BOOL CMainFrame::CmdOpenMap( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("打开地图指令解析出错！\n");
		return FALSE;
	}
	char psBmpFileName[256];
	sprintf( psBmpFileName, "Map/%s", strTemp );

	if( !GetSlice( strTemp, strCommand, 2 ) )
	{
		OutputDebugString("打开地图指令解析出错！\n");
		return FALSE;
	}
	char psMapFileName[256];
	sprintf( psMapFileName, "Map/%s", strTemp );

	if( !GetSlice( strTemp, strCommand, 3 ) )
	{
		OutputDebugString("打开地图指令解析出错！\n");
		return FALSE;
	}
	char psNpcFileName[256];
	sprintf( psNpcFileName, "Map/%s", strTemp );

	m_pGameMap->LoadMap( psBmpFileName, psMapFileName, psNpcFileName );
	return TRUE;
}

// 设置地图显示的左上角位置
BOOL CMainFrame::CmdSetMapLeftTop( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("设置地图显示的左上角位置指令解析出错！\n");
		return FALSE;
	}
	int nLeft = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 2 ) )
	{
		OutputDebugString("设置地图显示的左上角位置指令解析出错！\n");
		return FALSE;
	}
	int nTop = atoi( strTemp );

    m_pGameMap->SetLeftTop( nLeft, nTop );

	return TRUE;
}

// 设置地图显示的中心位置
BOOL CMainFrame::CmdSetMapCenterGride( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("设置地图显示的中心位置指令解析出错！\n");
		return FALSE;
	}
	int nGrideX = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 2 ) )
	{
		OutputDebugString("设置地图显示的中心位置指令解析出错！\n");
		return FALSE;
	}
	int nGrideY = atoi( strTemp );

    // 调整坐标
    nGrideX -= 9;
    nGrideY -= 6;

    int nLeft = nGrideX * TILE_W;
    int nTop  = nGrideY * TILE_H;

	m_pGameMap->SetLeftTop( nLeft, nTop );

	return TRUE;
}

// 打开脚本文件
BOOL CMainFrame::CmdOpenScript( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("打开脚本指令解析出错！\n");
		return FALSE;
	}
	int id = atoi( strTemp );

	// 为避免ScriptProc函数嵌套执行，这里不能使用如下两条语句：
	// m_pScript->OpenScript( id );
	// ScriptProc();
	// 而应当使用发送事件消息的方法引发脚本处理
	m_nLastCommandType = 0;
	PostMessage( ID_GAME_MESSAGE, id, 0 );

	return TRUE;
}

// 设置游戏状态
BOOL CMainFrame::CmdSetGameStatus( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString("设置游戏状态指令解析出错！\n");
		return FALSE;
	}

	if( strTemp == "GAME_ST_START" )
		m_nST = GAME_ST_START;
	else if( strTemp == "GAME_ST_DIALOG" )
		m_nST = GAME_ST_DIALOG;
	else if( strTemp == "GAME_ST_WALK" )
		m_nST = GAME_ST_WALK;
	else if( strTemp == "GAME_ST_FIGHT" )
		m_nST = GAME_ST_FIGHT;
	else
	{
		OutputDebugString("设置游戏状态指令解析出错！\n");
		return FALSE;
	}

	return TRUE;
}

// 设置地图值
BOOL CMainFrame::CmdSetMap( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString( "设置地图值指令解析出错！\n" );
		return FALSE;
	}
	int x = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 2 ) )
	{
		OutputDebugString( "设置地图值指令解析出错！\n" );
		return FALSE;
	}
	int y = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 3 ) )
	{
		OutputDebugString( "设置地图值指令解析出错！\n" );
		return FALSE;
	}
	int value = atoi( strTemp );

	// 得到w
	if( !GetSlice( strTemp, strCommand, 4 ) )
	{
		// 没有后续参数，则修改单个地图格内容
		// 执行命令
		// 数值合法性判断
		if( x<0 || x>199 || y<0 || y>199 || value<1 || value>800 )
		{
			OutputDebugString( "设置地图值指令解析出错！\n" );
			return FALSE;
		}

		m_pGameMap->map[x][y] = value;
		return TRUE;
	}
	int w = atoi( strTemp );

	// 得到h
	if( !GetSlice( strTemp, strCommand, 5 ) )
	{
		OutputDebugString( "设置地图值指令解析出错！\n" );
		return FALSE;
	}
	int h = atoi( strTemp );

	for( int i=0; i<w; i++ )
	{
		for( int j=0; j<h; j++ )
		{
			// 数值合法性判断
			if(!( (x + i)<0 || (x + i)>199 || (y + j)<0 || (y + j)>199 || value<1 || value>800 ))
				m_pGameMap->map[x + i][y + j] = value;
		}
	}

	return TRUE;
}

// 设置NPC值
BOOL CMainFrame::CmdSetNpc( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString( "设置NPC值指令解析出错！\n" );
		return FALSE;
	}
	int x = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 2 ) )
	{
		OutputDebugString( "设置NPC值指令解析出错！\n" );
		return FALSE;
	}
	int y = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 3 ) )
	{
		OutputDebugString( "设置NPC值指令解析出错！\n" );
		return FALSE;
	}
	int value = atoi( strTemp );

	// 得到w
	if( !GetSlice( strTemp, strCommand, 4 ) )
	{
		// 没有后续参数，则修改单个地图格内容
		// 执行命令
		// 数值合法性判断
		if( x<0 || x>199 || y<0 || y>199 || value<0 || value>800 )
		{
			OutputDebugString( "设置地图值指令解析出错！\n" );
			return FALSE;
		}

		m_pGameMap->npc[x][y] = value;
		return TRUE;
	}
	int w = atoi( strTemp );

	// 得到h
	if( !GetSlice( strTemp, strCommand, 5 ) )
	{
		OutputDebugString( "设置地图值指令解析出错！\n" );
		return FALSE;
	}
	int h = atoi( strTemp );

	for( int i=0; i<w; i++ )
	{
		for( int j=0; j<h; j++ )
		{
			// 数值合法性判断
			if(!( (x + i)<0 || (x + i)>199 || (y + j)<0 || (y + j)>199 || value<0 || value>800 ))
				m_pGameMap->npc[x + i][y + j] = value;
		}
	}

	return TRUE;
}

// 添加一个新的NPC
BOOL CMainFrame::CmdAddNpc( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString( "添加NPC指令解析出错！\n" );
		return FALSE;
	}
	int x = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 2 ) )
	{
		OutputDebugString( "添加NPC指令解析出错！\n" );
		return FALSE;
	}
	int y = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 3 ) )
	{
		OutputDebugString( "添加NPC指令解析出错！\n" );
		return FALSE;
	}
	int type = atoi( strTemp );

	// 数值合法性判断
	if( x<0 || x>199 || y<0 || y>199 || type<1 || type>10 )
	{
		OutputDebugString( "添加NPC指令解析出错！\n" );
		return FALSE;
	}

	// 执行命令
	m_pGameMap->AddNpc( x, y, type );
	return TRUE;
}

// 设置BOSS位置，开始BOSS作战
BOOL CMainFrame::CmdSetBoss(  CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString( "设置BOSS指令解析出错！\n" );
		return FALSE;
	}
	int X = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 2 ) )
	{
		OutputDebugString( "设置BOSS指令解析出错！\n" );
		return FALSE;
	}
	int Y = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 3 ) )
	{
		OutputDebugString( "设置BOSS指令解析出错！\n" );
		return FALSE;
	}
	int event = atoi( strTemp );

	if( !GetSlice( strTemp, strCommand, 4 ) )
	{
		OutputDebugString( "设置BOSS指令解析出错！\n" );
		return FALSE;
	}
	char* name = strTemp.GetBuffer(0);

	// 数值合法性判断
	if( X<0 || X>199 || Y<0 || Y>199 || event<11 || event>800 )
	{
		OutputDebugString( "设置BOSS指令解析出错！\n" );
		return FALSE;
	}

	// 执行命令
	m_pGameMap->SetBoss( X, Y, event, name );
	return TRUE;
}

// 保存游戏进度
BOOL CMainFrame::CmdSaveGame( CString& strCommand )
{
	CString strTemp;
	if( !GetSlice( strTemp, strCommand, 1 ) )
	{
		OutputDebugString( "设置NPC值指令解析出错！\n" );
		return FALSE;
	}
	int nScript = atoi( strTemp );

	// nScript参数指出恢复游戏时需要调用的脚本
	SaveGame( nScript );
	return TRUE;
}

void CMainFrame::OnNcMouseMove(UINT nHitTest, CPoint point)
{
	//鼠标在标题栏的时候，恢复箭头光标的代码添加在这里
	//本版本尚不存在此问题
	CFrameWnd::OnNcMouseMove(nHitTest, point);
}
// END